﻿package Server.AHMJ.MDMJ;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.lang.StringUtils;
import org.json.JSONObject;

import Server.Agent.GameDB;
import Server.Model.Base.IRoom;
import Server.Model.Base.IServerUserItem;
import Server.Model.Base.SHMUser;
import Server.Model.Hall.QpGameMgr;
import Server.Model.Hall.dthall;
import club.ClubRedis;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import redis.protocal.DbInfoMgr;

class GpsData {
	public int id;
	public boolean warn;
	public int sendWarn;
	public double lat;
	public double lon;

	public GpsData() {
		warn = false;
		sendWarn = 0;
		lat = 0;
		lon = 0;
	}
}

public class MajTable extends IRoom {

	M_tempAction m_tempAction[] = new M_tempAction[4];

	{
		for (int i = 0; i < 4; i++) {
			m_tempAction[i] = new M_tempAction();
		}
	}

	@Override
	public int GetID() {
		return m_dwTableID;
	};

	@Override
	public String GetType() {
		return "MDMJ";
	};

	@Override
	public int GetCreator() {
		return m_Creator;
	}

	@Override
	public void OnClientClose(int uid) {
		OnUserStandUp(uid, false);
	};

	@Override
	public int CanSit(int _Uid) {

		SHMUser user = dthall.getInstance().getUserInfo(_Uid);
		if (user != null) {
			int check = m_maxCostGem;
			if (this.m_hqInZuanNum != 0 && this.m_hqInZuanNum > check)
				check = this.m_hqInZuanNum;
			if (user.getGem(0) < check) {
				if (m_payWay != "FZPAY") {
					return 11;
				}
			}
		}

		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == _Uid) {
				return i;
			}
		}
		this.m_hqIpLimit = false;
		if (this.m_hqGpsLimit) {
			// TODO
		}

		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == 0) {
				return i;
			}
		}
		return 12;
	};

	@Override
	public int FindSeat(int _Uid) {
		for (int bySeatID = 0; bySeatID < 4; bySeatID++) {
			if (m_pIUserItem[bySeatID].dwUserID == _Uid) {
				return bySeatID;
			}
		}
		return Constants.INVALID_CHAIR;
	}

	MajLogic m_MajLogic = new MajLogic();
	MajPaiQiang m_MajPaiQiang = new MajPaiQiang();
	MajPaiQiangNoFeng m_MajPaiQiangNoFeng = new MajPaiQiangNoFeng();
	// int m_caiShen = Constants.INVALID_CARD;

	boolean m_bTianHu; // 天胡可能
	boolean m_bDiHu[] = new boolean[4]; // 地胡可能
	boolean m_bRenHu[] = new boolean[4]; // 人胡可能
	boolean m_bQiangGangHu[] = new boolean[4]; // 抢杠胡
	boolean m_bTing[] = new boolean[4];
	boolean m_bDiTing[] = new boolean[4]; // 地听可能

	int m_byTing[] = new int[4];// 霍邱麻将不停牌随时可换张，豹子例外
	int m_byChuPaiCount[] = new int[4]; // 出了多少张牌可能
	boolean m_baoZiTing[] = new boolean[4];// 霍邱麻将起手听牌就是豹子
	boolean m_startGpsCheck = false;
	GpsData m_gpsData[] = new GpsData[4]; // gps数据
	/**
	 * 霍邱麻将带大牌
	 */
	boolean m_hqDaiDaPai = true;
	boolean m_hqShuiDaShuiBao = false;

	boolean m_hqQiangGangZiMo = false;
	boolean m_hqGangHoux4 = false;
	boolean m_hqMinAnGang = true;
	boolean m_hqYiPaoSanXiang = false;
	boolean m_hqShiFouZhanZhuang = false;
	/**
	 * 不准吃牌
	 */
	boolean m_buzhunchipai = false;

	/**
	 * 允许站桩
	 */
	boolean m_yunxuzhanzhaung = false;
	boolean m_hqTianLuoDiHu = false;
	boolean m_hasYiPaoSanXiang = false;
	public boolean m_hqIpLimit = false;
	public boolean m_hqGpsLimit = false;
	public int m_hqInZuanNum = 0;
	public int m_winSeatId = -1;
	public int m_lostSeatId = -1;
	public int m_LastSeatId = -1;
	boolean m_isHuGangShangHua = false;
	int m_roundHuCount = 0;
	int m_roundHuGetCount = 0;
	int m_roundHuSeated[] = new int[4];
	int m_dingQuemj = 0;
	int m_cntMingGang[] = new int[4];
	int m_cntAnGang[] = new int[4];
	int m_cntBuGang[] = new int[4];
	int m_cntDianGang[] = new int[4];

	int m_vecChiSide[] = new int[4];
	boolean m_bTestGangShangGang = false;// 杠上杠的可能性

	int m_cntLianGang = 0;

	boolean m_isBusy = false;
	long m_dwLastDoCmdTime;
	int m_byRight[][] = new int[4][6];
	boolean m_bIsHu[] = new boolean[4]; // 是否胡了
	tagUserReport m_kReport[] = new tagUserReport[4];

	{
		for (int i = 0; i < 4; i++) {
			m_kReport[i] = new tagUserReport();
		}
	}

	int m_byKeHuPai[][] = new int[4][13];

	Long m_lStartTime;
	long needDealTime;
	public int m_dwTableID;
	long m_dismissTimer;
	int m_byAgreeDismiss[] = new int[4];
	boolean m_bTableStarted;
	boolean m_bGameStarted;
	int m_byRound;
	int m_byMaxRound;
	int m_wChuPaiDelay;
	int m_wFaPaiDelay;// 发牌延迟
	long m_wRobotSeconds[] = new long[4]; // 等待时长
	int nextPai = 0;// 控制得到下张牌
	int seatId = -1;
	int dingqueren = 0;
	int l_seat = -1;
	int l_handMj[] = new int[13];
	long m_wJieSuanRound;
	public int m_byCostGem;
	public int m_maxCostGem;
	public int m_diFen = 0;// 平牌分
	public int m_daifengpai = 0;
	public int m_fdFen = 0;
	public int m_zhunRuZuanNum = 0;

	public int m_MPHu = 0;
	public int zhuang_num = 0;

	public String m_payWay;
	public String m_strParam;
	public String m_strRoomDesc;

	public String[] m_vecParam;

	public int m_lastZhuang = 0;
	public int m_byZhuang;// 当前庄位置
	public int m_byLianZhuang;// 当前庄位置
	public int m_vecWinScore[] = new int[5];
	public int m_vecLoseScore[] = new int[5];
	public int m_vecGangScore[] = new int[5];
	public int m_vecRoundScore[] = new int[5];
	public int m_vecResultScore[] = new int[5];
	public int m_vecResultDingQue[] = new int[4];
	public String m_vecInputWenZi;
	public int m_vecZiMo[] = new int[5];
	public String[] m_TouXiang = new String[5];
	public BLOCK_GANGINFO m_vecGangInfo[][] = new BLOCK_GANGINFO[4][4];

	public String[] m_vecHuType = new String[5];
	public int m_nPiao;

	public int m_Creator;// 房主

	// int[] isMingpai= new int[4]; // 是否明牌
	int firstMingpai = -1; // 第一个亮牌玩家
	int roundScore[] = new int[4];// 输赢分数
	int LastOutNum = 0; // 是否是一炮多响
	int LastOutOld[] = new int[4]; // 上一家分数
	boolean IsLastfirst = false;// 是否是一炮多响,算杠
	int[] isLastHu = new int[4];

	IServerUserItem m_pIUserItem[] = new IServerUserItem[5]; // 用户指针

	{
		for (int i = 0; i < m_pIUserItem.length; i++) {
			m_pIUserItem[i] = new IServerUserItem();
		}
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				m_vecGangInfo[i][j] = new BLOCK_GANGINFO();
			}
			m_gpsData[i] = new GpsData();
		}
	}

	long m_LookOnUserID[] = new long[50];// 观众

	public int m_createTime = 0;

	MajTable() {
		m_createTime = (int) (System.currentTimeMillis() / 1000);
		m_byZhuang = 0;
		m_byLianZhuang = 1;
		m_Creator = 0;
		m_wJieSuanRound = 0L;
		m_bTableStarted = false;
		m_strParam = "";
		m_strRoomDesc = "";
		m_byCostGem = 0;
		m_maxCostGem = 0;
		m_payWay = "FZPAY";
		m_byRound = 0;
		m_byMaxRound = 0;
		m_nPiao = 0;
		m_startGpsCheck = false;
	}

	void Init(int cbReason) {			
		m_vecInputWenZi="";	
		Constants.memset(LastOutOld, 0, 4);
		Constants.memset(roundScore, 0, 4);
		Constants.memset(isLastHu, 0, 4);
		firstMingpai = -1;
		LastOutNum = 0;
		IsLastfirst = false;
		dingqueren = 0;
		m_bGameStarted = false;
		m_isBusy = false;
		m_dwLastDoCmdTime = 0L;
		m_bTianHu = true;
		m_wChuPaiDelay = 0;
		m_wFaPaiDelay = 0;
		m_wDealErrorDelay = 1;
		m_bTestGangShangGang = false;
		m_isHuGangShangHua = false;
		m_roundHuCount = 0;
		m_roundHuGetCount = 0;
		m_winSeatId = -1;
		m_lostSeatId = -1;
		for (int i = 0; i < 4; i++) {
			m_roundHuSeated[i] = -1;
		}

		m_cntLianGang = 0;

		CleanTempAction();

		for (int i = 0; i < 4; i++) {

			if (i == m_byZhuang) {
				m_bDiHu[i] = false;// 庄没有地胡这一说
				m_bRenHu[i] = false;// 庄没有人胡这一说
			} else {
				m_bDiHu[i] = true;
				m_bRenHu[i] = true;
			}

			m_bDiTing[i] = false;
			m_baoZiTing[i] = false;
			m_bQiangGangHu[i] = false;
			// m_bDiHu[i] = true;
			// m_bRenHu[i] = true;
			m_bTing[i] = false;
			m_bIsHu[i] = false;

			m_byTing[i] = 0;
			m_byChuPaiCount[i] = 0;

			m_cntMingGang[i] = 0;
			m_cntAnGang[i] = 0;
			m_cntBuGang[i] = 0;

			m_cntDianGang[i] = 0;

			m_vecGangInfo[i][0].reset();
			m_vecGangInfo[i][1].reset();
			m_vecGangInfo[i][2].reset();
			m_vecGangInfo[i][3].reset();

			m_wRobotSeconds[i] = 0L;

			m_vecChiSide[i] = Constants.INVALID_CHAIR;

			Constants.memset(m_byKeHuPai[i], Constants.INVALID_CARD, 13);

			m_pIUserItem[i].cbUserStatus = Constants.US_NULL;
			m_vecGangScore[i] = 0;
			m_vecResultDingQue[i] = 0;
			m_vecRoundScore[i] = 0;
			m_vecZiMo[i] = 0;
			m_vecHuType[i] = "";
		}
		for (int i = 0; i < 4; i++) {
			m_byRight[i][0] = 0;
			m_byRight[i][1] = 0;
			m_byRight[i][2] = 0;
			m_byRight[i][3] = 0;
			m_byRight[i][4] = 0;
			m_byRight[i][5] = 0;

		}

		if (Constants.INIT_TOTAL == cbReason) {
			m_bTableStarted = false;
			m_dismissTimer = 0L;
			m_wJieSuanRound = 0L;
			m_byAgreeDismiss[0] = 0;
			m_byAgreeDismiss[1] = 0;
			m_byAgreeDismiss[2] = 0;
			m_byAgreeDismiss[3] = 0;

			// Constants.memset(&m_kReport, 0, Constants.sizeof(m_kReport));
			// //add

			// Constants.memset(m_pIUserItem, 0,
			// Constants.sizeof(m_pIUserItem)); //add
			Constants.memset(m_LookOnUserID, 0, Constants.sizeof(m_LookOnUserID)); //
			m_MajLogic.Init(Constants.INIT_TOTAL);
			m_byRound = 0;
			m_byZhuang = 0;
			for (int i = 0; i < 4; i++) {
				m_vecWinScore[i] = 0;
				m_vecLoseScore[i] = 0;
				m_vecResultScore[i] = 0;
			}
		}
		if (Constants.INIT_FIRST_ROUND == cbReason) {
			m_MajLogic.Init(Constants.INIT_FIRST_ROUND);
		}
		if (Constants.INIT_NEWROUND == cbReason) {
			m_MajLogic.Init(Constants.INIT_NEWROUND);
		}
	}

	void clearRoundHu() {
		this.m_hasYiPaoSanXiang = false;
		this.m_roundHuCount = 0;
		this.m_roundHuGetCount = 0;
		for (int i = 0; i < 4; i++) {
			m_roundHuSeated[i] = -1;
		}
	}

	void clearUserHuRound(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] == seatId) {
				m_roundHuSeated[i] = -1;
			}
		}
	}

	boolean IsYiPaoSanXiang() {
		int count = 0;
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0)
				count++;
		}
		return count > 1;
	}

	boolean IsInRoundHu(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] == seatId)
				return true;
		}
		return false;
	}

	boolean IsFirstRoundHu(int seatId) {
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0 && m_roundHuSeated[i] == seatId)
				return true;
			else if (m_roundHuSeated[i] >= 0 && m_roundHuSeated[i] != seatId)
				return false;
		}
		return false;
	}

	int GetRoundHuIndex(int seatId) {
		int index = 0;
		for (int i = 0; i < 4; i++) {
			if (m_roundHuSeated[i] >= 0) {
				if (m_roundHuSeated[i] == seatId)
					return index;
				else
					index++;
			}
		}
		return -1;
	}

	boolean IsTingPaiKeHu(int bySeatID, int byMj) {
		if (m_bTing[bySeatID]) {
			for (int i = 0; i < 13; i++) {
				if (byMj != Constants.INVALID_CARD && m_byKeHuPai[bySeatID][i] == byMj) {
					return true;
				}
			}
		}
		return false;
	}

	void KickRobots() {
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {

			}
		}
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {

			}
		}
	}

	boolean HasRobot() {
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {
				return true;
			}
		}
		return false;
	}

	void SendAvatar(int _Uid) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		String iter = dthall.getInstance().Handle_OnGetUserAvatar(_Uid);
		SUBCMD_S_Avatar cmd = new SUBCMD_S_Avatar();
		cmd.m_lUid = _Uid;
		if (!StringUtils.isEmpty(iter)) {
			m_TouXiang[wChairID] = iter;
			cmd.szAvatarURL = iter;
		} else {
			cmd.szAvatarURL = "http://lamj.qilehuyu.cn/liuan-80.png";
		}

		SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
	}

	public void SendLocationData(SHMUser user) {
		JSONObject data = new JSONObject();
		data.put("loc", user.getGpsLocInfo());
		data.put("uid", user.getUid());
		data.put("command", "GPS_LOC");
		SendTableData(Constants.INVALID_CARD, data.toString());

		for (short i = 0; i < m_pIUserItem.length; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				if (m_pIUserItem[i].isAndroidUser == 0) {
					int uid = m_pIUserItem[i].dwUserID;
					SHMUser other = dthall.getInstance().getUserInfo(uid);
					data.put("uid", other.getUid());
					data.put("loc", other.getGpsLocInfo());
					dthall.getInstance().onSend(user.getUid(), data.toString());
				}
			}
		}
	}

	public void SendGpsData(SHMUser user) {
		JSONObject data = new JSONObject();
		List<Double> gpsData = user.getLocateInfo();
		data.put("lng", gpsData.get(0));
		data.put("lat", gpsData.get(1));
		data.put("command", "GPS_DATA");
		data.put("uid", user.getUid());
		SendTableData(Constants.INVALID_CHAIR, data.toString());

		for (short i = 0; i < m_pIUserItem.length; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				if (m_pIUserItem[i].isAndroidUser == 0) {
					int uid = m_pIUserItem[i].dwUserID;
					SHMUser other = dthall.getInstance().getUserInfo(uid);
					if (other != null) {
						gpsData = other.getLocateInfo();
						data.put("uid", other.getUid());
						data.put("lng", gpsData.get(0));
						data.put("lat", gpsData.get(1));
						dthall.getInstance().onSend(user.getUid(), data.toString());
					}
				}
			}
		}
	}

	public void OnUserSit(int _Uid) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 5) {
			m_pIUserItem[bySeatID].cbOnline = Constants.US_NULL;
		}
		SHMUser user = dthall.getInstance().getUserInfo(_Uid);
		if (user != null) {
			SendGpsData(user);
			SendLocationData(user);
		}
		if (user != null) {
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID == _Uid) {
					m_wRobotSeconds[i] = 0L;
					m_pIUserItem[i].dwUserID = _Uid;

					m_pIUserItem[i].wChairID = i;
					m_pIUserItem[i].dwFaceID = user.getAvatar();
					m_pIUserItem[i].cbGender = user.getSex();
					m_pIUserItem[i].cbOnline = 0;
					m_pIUserItem[i].szNickName = user.getNickName(null);
					m_pIUserItem[i].szIP = user.getIP(null);

					SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();

					cmd.m_lUid = _Uid;
					cmd.m_wUserChairID = m_pIUserItem[i].wChairID;
					cmd.m_dwTableID = m_dwTableID;
					cmd.m_lUserScore = m_pIUserItem[i].lUserScore;
					cmd.m_cbGender = m_pIUserItem[i].cbGender;
					cmd.m_iAvatar = m_pIUserItem[i].dwFaceID;
					cmd.szNickName = user.getNickName(null);
					cmd.szIP = m_pIUserItem[i].szIP;

					SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

					if (m_bGameStarted) {
						SendGameScene(_Uid, Constants.GS_PLAYING);
						SendKeHuPai();
					} else {
						SendGameScene(_Uid, Constants.GS_FREE);
					}

					SendAvatar(m_pIUserItem[i].dwUserID);
					return;
					// return m_pIUserItem[i].wChairID;
				}
			}
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID == 0) {
					m_wRobotSeconds[i] = 0L;
					m_pIUserItem[i].dwUserID = _Uid;
					m_pIUserItem[i].lUserScore = 0;
					m_pIUserItem[i].wChairID = i;
					m_pIUserItem[i].dwFaceID = user.getAvatar();
					m_pIUserItem[i].cbGender = user.getSex();
					m_pIUserItem[i].cbOnline = 0;
					m_pIUserItem[i].szNickName = user.getNickName(null);
					m_pIUserItem[i].szIP = user.getIP(null);

					SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();

					cmd.m_lUid = _Uid;
					cmd.m_wUserChairID = m_pIUserItem[i].wChairID;
					cmd.m_dwTableID = m_dwTableID;
					cmd.m_lUserScore = m_pIUserItem[i].lUserScore;
					cmd.m_cbGender = m_pIUserItem[i].cbGender;
					cmd.m_iAvatar = m_pIUserItem[i].dwFaceID;
					cmd.szNickName = user.getNickName(null);
					cmd.szIP = m_pIUserItem[i].szIP;

					SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

					if (m_bGameStarted) {
						SendGameScene(_Uid, Constants.GS_PLAYING);
					} else {
						SendGameScene(_Uid, Constants.GS_FREE);
					}

					class GpsTask extends TimerTask {

						@Override
						public void run() {
							// TODO Auto-generated method stub
							checkGPS();
						}
					}

					Timer timer = new Timer();
					timer.schedule(new GpsTask(), 20000);
					return;
					/// return m_pIUserItem[i].wChairID;
				}
			}

		}
		return;
		// return (int)Constants.INVALID_CHAIR;
	}

	void checkGPS() {
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == 0) {
				return;
			}
		}

		if (m_startGpsCheck == true) {
			return;
		}
		m_startGpsCheck = true;
		try {
			int red_seat[] = new int[4];
			String sWarnNoGPS = "";
			String sWarnStr = "";
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					String sNickName = m_pIUserItem[i].szNickName;
					m_gpsData[i].id = m_pIUserItem[i].dwUserID;
					if (m_gpsData[i].lat == 0 || m_gpsData[i].lon == 0) {
						if (sWarnNoGPS.length() == 0) {
							sWarnNoGPS += m_pIUserItem[i].szNickName;
						} else {
							sWarnNoGPS += "," + m_pIUserItem[i].szNickName;
						}
						red_seat[i] = m_pIUserItem[i].dwUserID;
						continue;
					}
					String strNear = "";
					for (int j = 0; j < 4; j++) {
						if (m_gpsData[j].lat == 0 || m_gpsData[j].lon == 0) {
							red_seat[j] = m_pIUserItem[j].dwUserID;
							continue;
						}
						if (i != j) {
							if (m_gpsData[i].lat == 0 || m_gpsData[i].lon == 0 || m_gpsData[j].lat == 0
									|| m_gpsData[j].lon == 0) {
								continue;
							}
							double distance = getDistance(m_gpsData[i].lat, m_gpsData[i].lon, m_gpsData[j].lat,
									m_gpsData[j].lon);

							if (distance < 100) {
								// 变化不超过100米，直接取消
								if (strNear.length() == 0) {
									strNear += m_pIUserItem[j].szNickName;
								} else {
									strNear += "," + m_pIUserItem[j].szNickName;
								}
								red_seat[i] = m_pIUserItem[i].dwUserID;
								red_seat[j] = m_pIUserItem[j].dwUserID;
							}
						}
					}
					if (strNear.length() > 0) {
						sWarnStr = sWarnStr + "玩家(" + sNickName + ")和(" + strNear + ")距离低于100米\n";
					}

				}
			}
			if (sWarnNoGPS.length() > 0) {
				sWarnStr = "玩家(" + sWarnNoGPS + ")未获取到GPS数据\n" + sWarnStr;
			}
			if (sWarnStr.length() > 0) {
				SUBCMD_S_GpsWarn cmd = new SUBCMD_S_GpsWarn();
				for (int i = 0; i < 4; i++) {
					cmd.red_seat[i] = red_seat[i];
				}

				cmd.ip_warn = "";
				cmd.gps_warn = sWarnStr;
				String sData = cmd.getJsonData();
				SendTableData(Constants.INVALID_CHAIR, sData);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	int FindSeat(long _Uid) {
		for (int bySeatID = 0; bySeatID < 4; bySeatID++) {
			if (m_pIUserItem[bySeatID].dwUserID == _Uid) {
				return bySeatID;
			}
		}
		return Constants.INVALID_CHAIR;
	}

	int GetPlayerCount() {
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				cntPlayer++;
			}
		}
		return cntPlayer;
	}

	int GetRobotCount() {
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].isAndroidUser == 1) {
				cntPlayer++;
			}
		}
		return cntPlayer;
	}

	public void OnUserStandUp(int _Uid, boolean leaveroom) {
		int wChairID = FindSeat(_Uid);
		if (m_bTableStarted == false && wChairID != 0 && leaveroom == true) {
			SUBCMD_S_StandUp cmd = new SUBCMD_S_StandUp();
			cmd.m_lUid = _Uid;
			cmd.m_wUserChairID = wChairID;
			cmd.m_dwTableID = m_dwTableID;
			SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
		}

		if (m_bTableStarted == false && leaveroom == true) {
			if (wChairID > 0 && wChairID < 5) {
				m_pIUserItem[wChairID].Init();
				QpGameMgr.getInstance().OnRemoveUserRoom(_Uid);
			} else {
			}
		} else {
			if (wChairID < 5) {
				m_pIUserItem[wChairID].cbOnline = Constants.US_OFFLINE;
			}
		}

	}

	// 踢人
	public void Handle_Kick(int _uid, String[] arg) {
		Integer _Uid = Integer.parseInt(arg[1]);
		int seat = FindSeat(_Uid);
		SUBCMD_S_Kick cmd = new SUBCMD_S_Kick();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = seat;
		SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
		m_pIUserItem[seat].Init();
		QpGameMgr.getInstance().OnRemoveUserRoom(_Uid);
	}
	
	public boolean HasParam(String szKey, boolean defaultValue) {
		for (int i = 0; i < m_vecParam.length; i++) {
			String key = m_vecParam[i];
			if (key.equals(szKey)) {
				return true;
			}
		}
		return defaultValue;
	}

	public void SetParam(String szParam) {
		m_strParam = szParam;

		m_vecParam = m_strParam.split(";");
	}

	public void SetDesc(String szDesc) {
		m_strRoomDesc = szDesc;

	}

	boolean SendYuPai() {
		SUBCMD_S_YuPai cmd = new SUBCMD_S_YuPai();
		if (m_daifengpai == 0) {
			cmd.byYuPai = m_MajPaiQiangNoFeng.GetYuPaiCount();
		} else {
			cmd.byYuPai = m_MajPaiQiang.GetYuPaiCount();
		}

		cmd.byCurrentUser = m_MajLogic.GetCurrentUser();

		SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());
		// SendLookonData(Constants.INVALID_CHAIR, cmd.getJsonData());
		return true;
	}

	boolean SendGameScene(int _Uid, int bGameStatus) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID >= 4) {
			return false;
		}
		{
			String tmpRoomDesc = "马店麻将" + m_strRoomDesc;

			SUBCMD_S_Param cmd = new SUBCMD_S_Param();
			cmd.m_dwTableID = m_dwTableID;
			cmd.szParam = m_strParam;
			cmd.szRoomDesc = tmpRoomDesc;
			SendTableData(Constants.INVALID_CHAIR, cmd.getJsonData());

		}

		int cntUser = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				cntUser++;
			}
		}
		{
						
			SUBCMD_S_Table cmd = new SUBCMD_S_Table();
			cmd.vecInputWenZi = m_vecInputWenZi;
			cmd.m_dwTableID = m_dwTableID;// 房间ID
			cmd.m_bTableStarted = m_bTableStarted ? 1 : 0;// 房间ID
			cmd.m_bGameStarted = m_bGameStarted ? 1 : 0;// 是否开始
			if (m_daifengpai == 0) {
				cmd.m_byYuPai = m_MajPaiQiangNoFeng.GetYuPaiCount();
			} else {
				cmd.m_byYuPai = m_MajPaiQiang.GetYuPaiCount();
			}

			cmd.m_byRound = m_byRound;
			cmd.m_byMaxRound = m_byMaxRound;
			cmd.m_cntLookon = 1;// 观众
			cmd.m_roomDesc = getRoomDesc();

			for (int i = 0; i < 4; i++) {
				cmd.m_seatInfo[i].m_lUid = m_pIUserItem[i].dwUserID;// UID
				cmd.m_seatInfo[i].m_iSeatId = i;// 座位号ID
				cmd.m_seatInfo[i].m_iTotalCoin = m_pIUserItem[i].lUserScore;

				cmd.m_seatInfo[i].m_NickName = m_pIUserItem[i].szNickName;// NICKNAME
				cmd.m_seatInfo[i].m_iBetCoin = 0;//
				cmd.m_seatInfo[i].m_cbGender = m_pIUserItem[i].cbGender;
				cmd.m_seatInfo[i].m_iAvatar = m_pIUserItem[i].dwFaceID;//
				cmd.m_seatInfo[i].m_cbUserStatus = m_pIUserItem[i].cbUserStatus;// 用户状态
				cmd.m_seatInfo[i].m_iVipLevel = m_pIUserItem[i].cbVipLevel;// VIP
																			// LEVEL
				cmd.m_seatInfo[i].m_iTitle = 0;// 称号
				cmd.m_seatInfo[i].m_isLookon = 0;// 是否观众
				cmd.m_seatInfo[i].szIP = m_pIUserItem[i].szIP;
			}

			SendData(_Uid, cmd.getJsonData());
			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					SendAvatar(m_pIUserItem[i].dwUserID);
				}
			}
		}

		if (m_bGameStarted == true) {
			{
				SUBCMD_S_TableBegin cmd = new SUBCMD_S_TableBegin();
				cmd.m_LastSeatId = m_lastZhuang;
				cmd.byLianZhuang = m_byLianZhuang;
				cmd.strParam = m_strParam;
				cmd.byZhuang = m_byZhuang;// 是否开始
				if (m_daifengpai == 0) {
					cmd.byYuPai = m_MajPaiQiangNoFeng.GetYuPaiCount();
				} else {
					cmd.byYuPai = m_MajPaiQiang.GetYuPaiCount();
				}
				cmd.byRound = m_byRound;
				cmd.byMaxRound = m_byMaxRound;
				cmd.byCurrentUser = m_MajLogic.GetCurrentUser();
				for (int i = 0; i < 4; i++) {
					cmd.lScore[i] = m_pIUserItem[i].lUserScore;
					cmd.lRoundScore[i] = m_vecRoundScore[i];
					cmd.DingQue[i] = m_vecResultDingQue[i];
				}

				cmd.byLastOutMj = m_MajLogic.GetLastOutMj();

				cmd.byGuiPai[0] = INVALID_CARD;
				cmd.byGuiPai[1] = INVALID_CARD;				
				SendData(_Uid, cmd.getJsonData());
			}

			{

				for (int i = 0; i < 4; i++) {
					if (m_pIUserItem[i].dwUserID > 0) {
						MajSide lMajSide = m_MajLogic.GetMajSide(i);
						SUBCMD_S_TableSide cmd = new SUBCMD_S_TableSide();
						cmd.bySeatID = i;
						cmd.byTing = m_bTing[i] ? 1 : 0;
						cmd.byBaoZi = m_baoZiTing[i] ? 1 : 0;
						Constants.memcpy(cmd.Maj, lMajSide.Maj, 14);
						if (i != bySeatID) {
							for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
								if (cmd.Maj[k] != Constants.INVALID_CARD) {
									if (m_bTing[i] == false) {
										cmd.Maj[k] = 99;
									} else {

									}
								}
							}
						}
						Constants.memcpy(cmd.Hua, lMajSide.Hua, 8);
						Constants.memcpy(cmd.hu, lMajSide.hu);
						Constants.memcpy(cmd.outMj, lMajSide.outMj, 20);
						Constants.memcpy(cmd.byRight, m_byRight[i], 6);

						SendData(_Uid, cmd.getJsonData());
					}
				}
			}

			{
				SUBCMD_S_TableEnd cmd = new SUBCMD_S_TableEnd();

				SendData(_Uid, cmd.getJsonData());
			}
		}

		return true;
	}

	public Replay Replay = new Replay();

	public boolean SendTableData(int wChairID, String sData) {
		// 群发用户
		if (wChairID == Constants.INVALID_CHAIR) {
			for (short i = 0; i < m_pIUserItem.length; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					if (m_pIUserItem[i].isAndroidUser == 0) {
						dthall.getInstance().onSend(m_pIUserItem[i].dwUserID, sData);
						Replay.AddJsonMsg(i, sData);
					} else {
						// mPlayers[i].SendGameMessage(wSubCmdID, pData,
						// wDataSize, data);
					}
				}
			}

			return true;
		} else {
			if (wChairID >= m_pIUserItem.length)
				return true;
			if (m_pIUserItem[wChairID].dwUserID > 0) {
				if (m_pIUserItem[wChairID].isAndroidUser == 0) {
					Replay.AddJsonMsg(wChairID, sData);
					dthall.getInstance().onSend(m_pIUserItem[wChairID].dwUserID, sData);
				} else {
					// mPlayers[wChairID].SendGameMessage(wSubCmdID, pData,
					// wDataSize, data);
				}
				return true;
			}
		}

		return false;
	}

	public boolean SendData(int wChairID, String sData) {
		// 群发用户
		if (wChairID == Constants.INVALID_CHAIR) {
			for (short i = 0; i < m_pIUserItem.length; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					if (m_pIUserItem[i].isAndroidUser == 0) {
						Replay.AddJsonMsg(i, sData);
						dthall.getInstance().onSend(m_pIUserItem[i].dwUserID, sData);
					} else {
						// mPlayers[i].SendGameMessage(wSubCmdID, pData,
						// wDataSize, data);
					}
				}
			}

			return true;
		} else {
			if (wChairID >= m_pIUserItem.length && wChairID >= 1000) {
				dthall.getInstance().onSend(wChairID, sData);
				int sit = FindSeat(wChairID);
				Replay.AddJsonMsg(sit, sData);
			} else if (m_pIUserItem[wChairID].dwUserID > 0) {
				if (m_pIUserItem[wChairID].isAndroidUser == 0) {
					Replay.AddJsonMsg(wChairID, sData);
					dthall.getInstance().onSend(m_pIUserItem[wChairID].dwUserID, sData);
				} else {
					// mPlayers[wChairID].SendGameMessage(wSubCmdID, pData,
					// wDataSize, data);
				}
				return true;
			}
		}

		return false;
	}

	void FaPai() {

		ZuoPai();

		if (m_byRound > m_byMaxRound) {
			return;
		}

		if (m_lastZhuang != m_byZhuang) {
			m_byLianZhuang = 1;
		}
		m_byRound = (m_byRound + 1);
		OnRoundInfoChange();
		Replay.SetIndexJushu(m_byRound);
		SUBCMD_S_FaPai cmd = new SUBCMD_S_FaPai();
		// Constants.memset(cmd,0,Constants.sizeof(cmd));
		cmd.byRound = m_byRound;
		cmd.byZhuang = m_byZhuang;
		cmd.byLianZhuang = m_byLianZhuang;
		cmd.byMaxRound = m_byMaxRound;
		cmd.byGuiPai[0] = INVALID_CARD;
		cmd.byGuiPai[1] = INVALID_CARD;
		cmd.lastZhuang = m_lastZhuang;
		for (int i = 0; i < 4; i++) {
			MajSide lMajSide = m_MajLogic.GetMajSide(i);
			lMajSide.SortCard();

			Constants.memcpy(cmd.byMj, lMajSide.Maj, 14);

			String sData = cmd.getJsonData();
			if (m_pIUserItem[i].isAndroidUser == 0) {
				SendData(m_pIUserItem[i].dwUserID, sData);
				m_wDealErrorDelay = 0;
			}
		}
		// ((dthall*)m_objAppHandler).onSendXLCH(_Uid,(char*)sData,sData.size());

	}

	void Test() {

	}

	static int byTestIndex = 0;

	void PrintPai() {
	}

	void CleanTempAction() {
		for (int i = 0; i < 4; i++) {
			m_tempAction[i].Clean();
		}
	}

	void CleanTempRight(int bySeatID) {

		if (bySeatID >= 0 && bySeatID < 4) {
			m_byRight[bySeatID][0] = 0;
			m_byRight[bySeatID][1] = 0;
			m_byRight[bySeatID][2] = 0;
			m_byRight[bySeatID][3] = 0;
			m_byRight[bySeatID][4] = 0;
			m_byRight[bySeatID][5] = 0;
		}
	}

	void CleanQiangGangHuRight(int bySeatID) {
		if (bySeatID >= 0 && bySeatID < 4) {
			m_bQiangGangHu[bySeatID] = false;
		}
		if (bySeatID == Constants.INVALID_CHAIR) {
			m_bQiangGangHu[0] = false;
			m_bQiangGangHu[1] = false;
			m_bQiangGangHu[2] = false;
			m_bQiangGangHu[3] = false;
		}
	}

	void ZuoPai() {
		if (m_daifengpai == 0) {
			m_MajPaiQiangNoFeng.Ruffle(1500);
		} else {
			m_MajPaiQiang.Ruffle(1500);
		}
		m_MajLogic.Init(Constants.INIT_NEWROUND);
		m_MajLogic.GetMajSide(0).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(1).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(2).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;
		m_MajLogic.GetMajSide(3).Maj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;

		// 卡五星
		// int byTest [] = {24, 25, 26,2,3,4,9,10,11,8,8,14,15,225};
		// 明四归
		// int byTest [] = {0,1,2,5,6,7,13,13,14,14,20,21,22,225};
		// 暗四归
		// int byTest [] = {0,0,0,0,1,1,1,1,2,2,2,2,13,225};
		// int byTest [] = {8,1,1,1,15,15,16,17,21,21,21,24,25,225};
		// int byTest1[] = { 11,12,12, 13, 25,26,17, 28, 19, 11, 15,22, 22,255
		// };
		int byTest3[] = { 18, 22, 13, 14, 15, 16, 21, 22, 27, 24, 31, 31, 31, 255 };
		int byTest1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 14, 255 };
		int byTest2[] = { 1, 1, 3, 3, 4, 4, 5, 5, 6, 8, 8, 11, 11, 13, 14, 255 };
		int byTest0[] = { 1, 1, 1, 6, 3, 3, 3, 4, 5, 5, 11, 11, 11, 15, 255 };
		int byTest4[] = { 11, 11, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19, 255 };
		int byTest5[] = { 21, 22, 23, 24, 25, 26, 27, 28, 29, 22, 22, 23, 23, 255 };
		int byTest6[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 31, 32, 32, 255 };
		int byTest7[] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 355 };
		int byTest8[] = { 1, 1, 1, 9, 9, 9, 11, 11, 11, 19, 19, 19, 21 };
		int byTest9[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 12, 14, 15, 255 };
		int byTest10[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 18, 18 };
		int byTest11[] = { 21, 21, 21, 11, 31, 31, 34, 31, 1, 1, 1, 1, 5 };
		int byTest12[] = { 24, 24, 24, 4, 27, 7, 34, 11, 13, 13, 15, 15, 17 };
		int byTest13[] = { 21, 21, 21, 13, 11, 34, 4, 13, 13, 27, 27, 27, 29 };
		int byTest14[] = { 2, 21,21, 21, 8, 22, 23, 34, 24, 26, 22, 32, 32 };
		for (int by = 0; by < Constants.HAND_MJ_MAX - 1; by++) {
			if (m_daifengpai == 0) {
				m_MajLogic.GetMajSide(0).Maj[by] = m_MajPaiQiangNoFeng.GetPai(0);
				m_MajLogic.GetMajSide(1).Maj[by] = m_MajPaiQiangNoFeng.GetPai(1);
				m_MajLogic.GetMajSide(2).Maj[by] = m_MajPaiQiangNoFeng.GetPai(2);
				m_MajLogic.GetMajSide(3).Maj[by] = m_MajPaiQiangNoFeng.GetPai(3);
			} else {
				// m_MajLogic.GetMajSide(0).Maj[by] = byTest13[by];
				// m_MajLogic.GetMajSide(1).Maj[by] = byTest14[by];

				// m_MajLogic.GetMajSide(2).Maj[by] = byTest3[by];

				// m_MajLogic.GetMajSide(3).Maj[by] = byTest3[by];
				m_MajLogic.GetMajSide(0).Maj[by] = m_MajPaiQiang.GetPai(0);
				m_MajLogic.GetMajSide(1).Maj[by] = m_MajPaiQiang.GetPai(1);
				m_MajLogic.GetMajSide(2).Maj[by] = m_MajPaiQiang.GetPai(2);
				m_MajLogic.GetMajSide(3).Maj[by] = m_MajPaiQiang.GetPai(3);
			}

		}
		/*
		 * HU hu = m_MajLogic.GetMajSide(0).hu; hu.block[0].style =
		 * Constants.BLOCK_PENG; hu.block[0].first = 1; hu.block[1].style =
		 * Constants.BLOCK_PENG; hu.block[1].first = 1; hu.block[2].style =
		 * Constants.BLOCK_PENG; hu.block[2].first = 1;
		 */

		// m_caiShen = 27;
		/*
		 * for (int i = 0; i < 4; i++) { if(m_pIUserItem[i].dwUserID == 5345) {
		 * for (int by = 0; by < Constants.HAND_MJ_MAX - 1; by++) {
		 * m_MajLogic.GetMajSide(i).Maj[by] = test1[m_byRound % 8][by]; }
		 * 
		 * m_caiShen = test1[m_byRound % 8][13];
		 * 
		 * break; } }
		 */
	}

	int GetActionRight(int bySeatID) {
		if (m_byRight[bySeatID][4] > 0) {
			return Constants.ACTION_HU;
		}
		if (m_byRight[bySeatID][2] > 0) {
			return Constants.ACTION_GANG;
		}
		if (m_byRight[bySeatID][1] > 0) {
			return Constants.ACTION_PENG;
		}
		if (m_byRight[bySeatID][0] > 0) {
			return Constants.ACTION_CHI;
		}
		return 0;
	}

	boolean HasQiangGangHuRight() {

		for (int i = 0; i < 4; i++) {
			if (m_bQiangGangHu[i]) {
				return true;
			}
		}

		return false;
	}

	boolean IsAllowChuPai(int bySeatID, int byOutMj) {
		if (m_pIUserItem[bySeatID].isAndroidUser == 1) {
			return true;
		}
		if (m_bTing[bySeatID] == false) {
			MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

			int cntHandMj = 0;
			int cntKeHuPai = 0;
			for (int i = 0; i < 14; i++) {
				int byTestMj = l_MajSide.Maj[i];
				boolean bKeHu = false;
				if (MajHelper.IsWTSZ(byTestMj)) {
					cntHandMj++;
					for (int j = 0; j < 4; j++) {
						if (j != bySeatID && m_bTing[j] != false) {
							for (int k = 0; k < 13; k++) {
								if (MajHelper.IsWTSZ(m_byKeHuPai[j][k])) {
									if (byTestMj == m_byKeHuPai[j][k]) {
										bKeHu = true;
										break;
									}
								}
							}
						}
					}
					if (bKeHu) {
						cntKeHuPai++;
					}
				}
				if (bKeHu == false) {
					break;
				}
			}
			if (cntHandMj == cntKeHuPai) {
				return true;
			} else {
				boolean bIsAllow = true;
				for (int j = 0; j < 4; j++) {
					if (j != bySeatID && m_bTing[j] != false) {
						for (int k = 0; k < 13; k++) {
							if (MajHelper.IsWTSZ(m_byKeHuPai[j][k])) {
								if (byOutMj == m_byKeHuPai[j][k]) {
									bIsAllow = false;
									break;
								}
							}
						}
					}
				}
				if (bIsAllow) {
					return true;
				} else {
					return false;
				}
			}
		}
		/*
		 * // 处理不能打明牌玩家胡的牌 if (m_bTing[bySeatID] == false) { MajSide l_MajSide =
		 * m_MajLogic.GetMajSide(bySeatID);
		 * 
		 * for (int byIndex = 0; byIndex < 4; byIndex++) { if (byIndex !=
		 * bySeatID && m_bTing[byIndex] != false) { int cntNotKeHuPai = 0; for
		 * (int i = 0; i < 13; i++) { if
		 * (MajHelper.IsWTSZ(m_byKeHuPai[byIndex][i])) { for (int k = 0; k < 14;
		 * k++) { if (MajHelper.IsWTSZ(l_MajSide.Maj[k])) { if(l_MajSide.Maj[k]
		 * != m_byKeHuPai[byIndex][i]) { cntNotKeHuPai++; }else{
		 * 
		 * } } } } } for (int i = 0; i < 13; i++) { if (byOutMj !=
		 * Constants.INVALID_CARD && m_byKeHuPai[byIndex][i] == byOutMj) {
		 * 
		 * if (cntNotKeHuPai > 0) { return false; } } } } } }
		 */
		return true;
	}

	boolean IsAllowHu(int bySeatID, int byOutMj) {
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		int byTempMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
		MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);
		boolean bFind = true;
		if (m_bTing[bySeatID]) {
			for (int i = 0; i < 13; i++) {
				if (byOutMj != Constants.INVALID_CARD && m_byKeHuPai[bySeatID][i] == byOutMj) {
					return true;
				}
			}
		}
		switch (m_vecResultDingQue[bySeatID]) {
		case 1:
			for (int i = 0; i < 13; i++) {
				if ((byTempMj[i] < 10) && (byTempMj[i] > 0)) {
					bFind = false;
					break;
				}

			}
			break;

		case 2:
			for (int i = 0; i < 13; i++) {
				if ((byTempMj[i] < 20) && (byTempMj[i] > 10)) {
					bFind = false;
					break;
				}

			}
			break;
		case 3:
			for (int i = 0; i < 13; i++) {
				if ((byTempMj[i] < 30) && (byTempMj[i] > 20)) {
					bFind = false;
					break;
				}

			}
			break;

		}
		if (bFind == false) {
			return false;
		}

		return bFind;
	}

	// 在豹子状态下是否可开杠
	boolean IsCanGangInBaoZi(int bySeatID, int byMoPai, boolean bZiMo) {
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		int byTempMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
		MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);

		MJ_GANGINFO mjAnGang = new MJ_GANGINFO();
		mjAnGang.GangMj = Constants.INVALID_CARD;
		mjAnGang.GangStyle = 0;
		if (bZiMo) {
			// 只可能出现明杠和暗杠，保证ting牌一致即可
			MJ_GANGINFO mjAnGang1 = MajHelper.IsAnGang(byTempMj, m_vecResultDingQue[bySeatID]);
			if (mjAnGang1.GangMj != Constants.INVALID_CARD) {
				mjAnGang = mjAnGang1;
				if (m_bTing[bySeatID] == true) {
					int byTingPai[] = new int[42];
					int byEmptyHua[] = new int[8];
					int oldTingPaiCount = MajHelper.GetTingPai(l_MajSide.Maj, l_MajSide.hu, byEmptyHua, byTingPai,
							m_vecResultDingQue[bySeatID]);
					int byTestGangMj[] = new int[Constants.HAND_MJ_MAX];
					HU testGangHu = l_MajSide.hu.clone();
					Constants.memcpy(byTestGangMj, byTempMj, Constants.sizeof(byTempMj));
					BLOCK gangBlock = MajHelper.AnGang(byTestGangMj, mjAnGang.GangMj);
					MajHelper.AddBlock(testGangHu, gangBlock);
					MajHelper.SortCard(byTestGangMj, Constants.HAND_MJ_MAX);
					int newByTingPai[] = new int[42];
					int newTingPaiCount = MajHelper.GetTingPai(byTestGangMj, testGangHu, byEmptyHua, newByTingPai,
							m_vecResultDingQue[bySeatID]);
					if (newTingPaiCount == oldTingPaiCount) {
						for (int i = 0; i < newTingPaiCount; i++) {
							if (byTingPai[i] != newByTingPai[i]) {
								return false;
							}
						}
						return true;
					}
				} else {
					return true;
				}
			}
		} else {
			MJ_GANGINFO mjAnGang1 = MajHelper.IsGang(byTempMj, byMoPai, m_vecResultDingQue[bySeatID]);
			if (mjAnGang1.GangMj == byMoPai) {
				mjAnGang = mjAnGang1;
			}
			if (mjAnGang.GangMj != Constants.INVALID_CARD) {
				int byTingPai[] = new int[42];
				int byEmptyHua[] = new int[8];
				int oldTingPaiCount = MajHelper.GetTingPai(l_MajSide.Maj, l_MajSide.hu, byEmptyHua, byTingPai,
						m_vecResultDingQue[bySeatID]);
				int byTestGangMj[] = new int[Constants.HAND_MJ_MAX];
				HU testGangHu = l_MajSide.hu.clone();
				Constants.memcpy(byTestGangMj, byTempMj, Constants.sizeof(byTempMj));
				BLOCK gangBlock = MajHelper.AnGang(byTestGangMj, mjAnGang.GangMj);
				MajHelper.AddBlock(testGangHu, gangBlock);
				MajHelper.SortCard(byTestGangMj, Constants.HAND_MJ_MAX);
				int newByTingPai[] = new int[42];
				int newTingPaiCount = MajHelper.GetTingPai(byTestGangMj, testGangHu, byEmptyHua, newByTingPai,
						m_vecResultDingQue[bySeatID]);
				if (newTingPaiCount == oldTingPaiCount) {
					for (int i = 0; i < newTingPaiCount; i++) {
						if (byTingPai[i] != newByTingPai[i]) {
							return false;
						}
					}
					return true;
				}
			}
		}
		return false;
	}

	// 杠后是否换叫
	boolean IsCanGang(int bySeatID, int byMoPai, boolean bZiMo) {
		return true;
	}

	boolean isCanChuPai(int bySeatID) {
		return true;
	}

	// 用户出牌
	boolean OnUserOutMj(int bySeatID, int byOutMj) {
		System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj 0: " + bySeatID + "-" + byOutMj);
		if (bySeatID >= 4 || !MajHelper.IsWTSZ(byOutMj)) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 1 ");
			return false;
		}
		if (m_bGameStarted == false) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 2 ");
			return false;
		}

		// m_MajLogic.GetMajSide(bySeatID).SetMoPai(byOutMj);
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

		m_wRobotSeconds[bySeatID] = 0L;
		if ((l_MajSide.GetHandMjCount() % 3) != 2) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserOutMj return false 3 " + "-"
					+ IJsonExport.sprintf_INT32(l_MajSide.Maj, 14));
			return false;
		}

		// 处理不能打明牌玩家胡的牌
		/*
		 * 不需要这个zws if (IsAllowChuPai(bySeatID, byOutMj) == false) {
		 * SUBCMD_C_BuXuChuPai cmd = new SUBCMD_C_BuXuChuPai(); cmd.byOutMj =
		 * byOutMj; String sData = cmd.getJsonData();
		 * SendData(m_pIUserItem[bySeatID].dwUserID, sData); return false; }
		 */
		CleanTempRight(bySeatID);
		CleanQiangGangHuRight(Constants.INVALID_CHAIR);

		m_MajLogic.SetCurrentAction(0);

		// 天胡
		if (m_bTianHu) {// 有人出过牌就不可能是天胡了
			m_bTianHu = false;
		}
		// 庄家以外出牌，人和否定
		if (m_bRenHu[bySeatID] && m_byChuPaiCount[bySeatID] >= 1) {
			m_bRenHu[bySeatID] = false;
		}

		if (m_bDiHu[bySeatID]) {// 在第一圈内 闲家胡 意思是没出过牌?
			m_bDiHu[bySeatID] = false;
		}
		if (bySeatID != m_byZhuang) {// 非庄出牌 开局后，庄家打出的第一张牌放铳给闲家胡的牌。
			for (int i = 0; i < 4; i++) {
				m_bDiHu[i] = false;
			}
		}

		m_byChuPaiCount[bySeatID]++;
		if (bySeatID == m_byZhuang && m_byChuPaiCount[bySeatID] == 1) {
			// 庄出第一张牌
		}

		// 取消操作权
		if (GetActionRight(bySeatID) > 0) {
			CleanTempRight(bySeatID);
		}

		// 牌值校验
		for (int byIndex = 0; byIndex < Constants.HAND_MJ_MAX; byIndex++) {
			if (l_MajSide.Maj[byIndex] == byOutMj) {
				// 有效删除麻将
				l_MajSide.Maj[byIndex] = Constants.INVALID_CARD;

				l_MajSide.ChuPai(byOutMj);

				l_MajSide.SortCard(Constants.HAND_MJ_MAX);

				break;
			}
		}

		m_MajLogic.SetCurrentUser(bySeatID);
		m_MajLogic.SetLastOutMj(byOutMj);
		// 发送数据结构
		SUBCMD_S_ChuPai cmd = new SUBCMD_S_ChuPai();
		cmd.byActionUser = bySeatID;
		cmd.byOutMj = byOutMj;

		// 发送数据
		int canHuNum = 0;
		for (int i = 0; i < 4; i++) {
			cmd.bHu = 0;
			cmd.bGang = 0;
			cmd.bPeng = 0;
			cmd.bChi = 0;
			int byIndex = bySeatID + i + 1;
			byIndex = byIndex % 4;
			MajSide l_MajSideTmp = m_MajLogic.GetMajSide(byIndex);
			// 下家,可以吃牌
			if (byIndex == MajHelper.GetNextUser(bySeatID)) {
				HU tempHu = new HU();
				if (IsAllowHu(byIndex, byOutMj)) {
					cmd.bHu = (MajHelper.IsHu(l_MajSideTmp.Maj, byOutMj, l_MajSideTmp.hu, tempHu, l_MajSideTmp.Hua,
							m_vecResultDingQue[byIndex]) ? 1 : 0);
					if (cmd.bHu == 1 && m_roundHuCount < 4) {
						this.m_roundHuSeated[this.m_roundHuCount] = byIndex;
						this.m_roundHuCount++;
					}
				}

				if (m_bTing[byIndex] == false && m_baoZiTing[byIndex] == false) {
					cmd.bPeng = (MajHelper.IsPeng(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) ? 1 : 0);
					cmd.bGang = MajHelper.IsGang(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]).GangStyle;
					// 控制吃不吃牌
					if (!m_buzhunchipai) {
						cmd.bChi = (MajHelper.IsChi(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) > 0 ? 1
								: 0);
					}
				} else if (m_baoZiTing[byIndex]) {
					// 豹子情况下判断特殊杠
					if (IsCanGangInBaoZi(byIndex, byOutMj, false)) {
						cmd.bGang = 1;
					}
				} else {
					cmd.bPeng = (MajHelper.IsPeng(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) ? 1 : 0);
					// 控制吃牌
					if (!m_buzhunchipai) {
						cmd.bChi = (MajHelper.IsChi(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) > 0 ? 1
								: 0);
					}
					if (IsCanGang(byIndex, byOutMj, false)) {
						cmd.bGang = MajHelper.IsGang(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]).GangStyle;
					}
				}

				// 操作权限
				if (m_bTing[byIndex] == false && m_baoZiTing[byIndex] == false) {

					if (cmd.bChi != 0) {
						m_byRight[byIndex][0] = 1;
					}
					if (cmd.bPeng != 0) {
						m_byRight[byIndex][1] = 1;
					}
				}
				if (cmd.bGang != 0) {
					m_byRight[byIndex][2] = 1;
				}
				if (cmd.bHu != 0) {
					m_byRight[byIndex][4] = 1;
				}

			} else if (bySeatID != byIndex) {
				HU tempHu = new HU();
				if (IsAllowHu(byIndex, byOutMj)) {
					cmd.bHu = (MajHelper.IsHu(l_MajSideTmp.Maj, byOutMj, m_MajLogic.GetMajSide(byIndex).hu, tempHu,
							m_MajLogic.GetMajSide(byIndex).Hua, m_vecResultDingQue[byIndex]) ? 1 : 0);
					if (cmd.bHu == 1 && m_roundHuCount < 4) {
						this.m_roundHuSeated[this.m_roundHuCount] = byIndex;
						this.m_roundHuCount++;
					}
				}

				if (m_bTing[byIndex] == false && m_baoZiTing[byIndex] == false) {
					cmd.bPeng = (MajHelper.IsPeng(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) ? 1 : 0);
					cmd.bGang = MajHelper.IsGang(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]).GangStyle;
					cmd.bChi = 0;
				} else {
					cmd.bPeng = 0;
					cmd.bChi = 0;
					if (m_baoZiTing[byIndex]) {
						// 在豹子情况下，不能随便明杠，保持听牌一致才行
						if (IsCanGangInBaoZi(byIndex, byOutMj, false)) {
							cmd.bGang = 1;
						}
					} else {
						cmd.bPeng = (MajHelper.IsPeng(l_MajSideTmp.Maj, byOutMj, m_vecResultDingQue[byIndex]) ? 1 : 0);
						if (IsCanGang(byIndex, byOutMj, false)) {
							cmd.bGang = MajHelper.IsGang(l_MajSideTmp.Maj, byOutMj,
									m_vecResultDingQue[byIndex]).GangStyle;
						}
					}
				}
				// 操作权限
				if (m_bTing[byIndex] == false && m_baoZiTing[byIndex] == false) {

					if (cmd.bChi != 0) {
						m_byRight[byIndex][0] = 1;
					}
					if (cmd.bPeng != 0) {
						m_byRight[byIndex][1] = 1;
					}

				}
				if (cmd.bGang != 0) {
					m_byRight[byIndex][2] = 1;
				}
				if (cmd.bHu != 0) {
					m_byRight[byIndex][4] = 1;
				}
			}

			// 余牌小于1不能杠
			if (m_daifengpai == 1 && m_MajPaiQiang.GetYuPaiCount() <= 0) {
				cmd.bGang = 0;
			}
			if (m_daifengpai == 0 && m_MajPaiQiangNoFeng.GetYuPaiCount() <= 0) {
				cmd.bGang = 0;
			}
			// 如果一轮过了，就不许胡了，必须等下一轮
			if (isLastHu[byIndex] != 0) {
				cmd.bHu = 0;
				m_byRight[byIndex][4] = 0;
			}
			if (cmd.bHu != 0) {
				canHuNum++;
			}
			m_MajLogic.m_byOutMjCount++;

			m_byRight[byIndex][0] = cmd.bChi;
			m_byRight[byIndex][1] = cmd.bPeng;
			m_byRight[byIndex][2] = cmd.bGang;
			m_byRight[byIndex][3] = 0;
			m_byRight[byIndex][4] = cmd.bHu;

			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);

			/*
			 * if (byIndex == bySeatID) { Constants.memcpy(cmd.byHandMj,
			 * l_MajSide.Maj, Constants.HAND_MJ_MAX); } else {
			 * Constants.memcpy(cmd.byHandMj, l_MajSide.Maj,
			 * Constants.HAND_MJ_MAX); for (int k = 0; k <
			 * Constants.HAND_MJ_MAX; k++) { if (cmd.byHandMj[k] !=
			 * Constants.INVALID_CARD) { cmd.byHandMj[k] = 0; } } }
			 */

			Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
			if (m_bTing[bySeatID] == false && m_baoZiTing[bySeatID] == false) {
				if (byIndex != bySeatID) {
					for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
						if (cmd.byHandMj[k] != Constants.INVALID_CARD) {
							cmd.byHandMj[k] = 99;
						}
					}
				}
			} else {

			}
			String sData = cmd.getJsonData();
			SendData(m_pIUserItem[byIndex].dwUserID, sData);
			m_wDealErrorDelay = 0;
		}

		/*
		 * boolean bHasHu = false; if(canHuNum > 1){ //必须按照顺序，距离出牌玩家的距离 int
		 * byNextUser = bySeatID; for (int i = 1; i < 4; i++) { byNextUser =
		 * MajHelper.GetNextUser(byNextUser); if ((m_bTing[byNextUser] ||
		 * m_baoZiTing[byNextUser]) && m_byRight[byNextUser][4] > 0) { bHasHu =
		 * true; SUBCMD_C_Hu hu = new SUBCMD_C_Hu(); OnUserHu(byNextUser, hu); }
		 * } } if (bHasHu) { return true; }
		 */
		// 霍邱要求胡必须玩家自己点这里在一炮三响的情况下需要特殊处理，必须判断出来用户是第几个胡（有可能用户选择过）
		// 等用户全部点击完成后在处理
		if (canHuNum <= 1) {
			clearRoundHu();
		} else {
			// 存在一炮三响的可能，等待用户点击完成
		}
		CleanTempAction();

		m_MajLogic.SetLastUser(bySeatID);
		// 无人有操作,下家摸牌
		for (int j = 0; j < 4; j++) {
			if (GetActionRight(j) > 0)
				break;
			else {
				// 无人有吃碰杠胡
				if (j == 3) {
					// 切换用户
					int byNextUser = MajHelper.GetNextUser(bySeatID);
					m_MajLogic.SetCurrentUser(byNextUser);
					m_isBusy = true;
					OnUserTouchMj(byNextUser, 0);
					m_isBusy = false;
				}
			}
		}

		return true;
	}

	boolean isCanMoPai(int bySeatID) {
		boolean bNeedWait = false;
		for (int i = 0; i < 4; i++) {
			if (GetActionRight(i) > 0) {
				bNeedWait = true;
			}
		}
		if (bNeedWait) {
			return false;
		}
		for (int i = 0; i < 4; i++) {
			MajSide tmp_MajSide = m_MajLogic.GetMajSide(i);
			if (tmp_MajSide.GetHandMjCount() % 3 != 1) {
				bNeedWait = true;
			}
		}
		if (bNeedWait) {
			return false;
		}

		// if(m_MajLogic.GetCurrentUser() != bySeatID &&
		// MajHelper.GetNextUser(m_MajLogic.GetCurrentUser()) != bySeatID)
		{
			// return false;
		}
		return true;
	}
	// 用户摸牌

	void OnMJMsg(int seat, int pai) {
		seatId = seat;
		nextPai = pai;
	}

	void OnZuoMj(int seat, int pai[]) {
		l_seat = seat;
		for (int i = 0; i < pai.length; i++) {
			l_handMj[i] = pai[i];
		}
	}

	public static int cnt_step = 0;

	boolean OnUserTouchMj(int bySeatID, int cbReason) {
		if (dingqueren != 4) {
			return false;
		}
		System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj 0: " + bySeatID);
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}

		if (isCanMoPai(bySeatID) == false) {
			return false;
		}
		switch (cbReason) {
		case Constants.ACTION_GANG_BUPAI:

			break;
		case Constants.ACTION_BU_HUA:

			break;
		default:

			break;
		}

		MajSide l_MajSide1 = m_MajLogic.GetMajSide(bySeatID);
		if ((l_MajSide1.GetHandMjCount() % 3) != 1) {
			System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj return false  " + bySeatID);
			return false;
		}
		//
		if (m_daifengpai == 1 && m_MajPaiQiang.IsEnd() != 0) {
			OnEventGameEnd(bySeatID, Constants.GAME_END_PASS);
			return false;
		}
		if (m_daifengpai == 0 && m_MajPaiQiangNoFeng.IsEnd() != 0) {
			OnEventGameEnd(bySeatID, Constants.GAME_END_PASS);
			return false;
		}
		CleanQiangGangHuRight(Constants.INVALID_CHAIR);
		// 胡牌过，清除
		isLastHu[bySeatID] = 0;

		if (cbReason != Constants.ACTION_GANG_BUPAI) {
			m_MajLogic.SetCurrentAction(0);
		}

		SUBCMD_S_MoPai cmd = new SUBCMD_S_MoPai();
		cmd.reason = cbReason;
		cmd.bySeatID = bySeatID;

		// 如果当前本身是自己操作 下次还是自己摸牌
		// 只有 杠 操作后摸牌
		boolean isGangMoPai = false;
		isGangMoPai = m_MajLogic.GetCurrentAction() == Constants.ACTION_GANG;

		// 设置成当前玩家
		m_MajLogic.SetCurrentUser(bySeatID);

		int byMoPai = Constants.INVALID_CARD;
		switch (cbReason) {
		case Constants.ACTION_GANG_BUPAI:
			if (nextPai != 0 && bySeatID == seatId) {
				if (m_daifengpai == 0) {
					byMoPai = m_MajPaiQiangNoFeng.GetZdPai(bySeatID, nextPai);
				} else {
					byMoPai = m_MajPaiQiang.GetZdPai(bySeatID, nextPai);
				}
				nextPai = 0;
				seatId = -1;// 重置 只获取一次指定牌
			} else {
				if (m_daifengpai == 0) {
					byMoPai = m_MajPaiQiangNoFeng.GetGangMoPai(bySeatID);
				} else {
					byMoPai = m_MajPaiQiang.GetGangMoPai(bySeatID);
				}

			}
			break;
		case Constants.ACTION_BU_HUA:
			if (m_daifengpai == 0) {
				byMoPai = m_MajPaiQiangNoFeng.GetBuHuaMoPai(bySeatID);
			} else {
				byMoPai = m_MajPaiQiang.GetBuHuaMoPai(bySeatID);
			}

			break;
		default:
			if (nextPai != 0 && bySeatID == seatId) {
				if (m_daifengpai == 0) {
					byMoPai = m_MajPaiQiangNoFeng.GetZdPai(bySeatID, nextPai);
				} else {
					byMoPai = m_MajPaiQiang.GetZdPai(bySeatID, nextPai);
				}
				nextPai = 0;
				seatId = -1;// 重置 只获取一次指定牌
			} else {
				if (m_daifengpai == 0) {
					byMoPai = m_MajPaiQiangNoFeng.GetPai(bySeatID);
				} else {
					byMoPai = m_MajPaiQiang.GetPai(bySeatID);
				}

				m_bTestGangShangGang = false;
				m_cntLianGang = 0;
			}
			break;
		}

		 //byMoPai=3;
		System.out.println("[" + m_dwTableID + "] " + "OnUserTouchMj 1: " + bySeatID + "-" + byMoPai);

		// byMoPai = 27;
		if (!MajHelper.IsWTSZ(byMoPai)) {
			OnEventGameEnd(bySeatID, Constants.GAME_END_PASS);
			return true;
		}
		for (int byIndex = 0; byIndex < 4; byIndex++) {
			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
			//// MajSide l_MajSide_mingpai = m_MajLogic.GetMajSide(byIndex);
			if (byIndex == bySeatID) {
				cmd.byMoPai = byMoPai;

				// 胡、杠牌判断
				// 自摸
				MajSide l_TmpMajSide = m_MajLogic.GetMajSide(byIndex);

				l_TmpMajSide.SetMoPai(byMoPai);
				int byTempMj[] = new int[Constants.HAND_MJ_MAX];
				Constants.memcpy(byTempMj, l_TmpMajSide.Maj, Constants.HAND_MJ_MAX);
				MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);

				HU temphu = new HU();
				int Hua[] = new int[8];
				MajHelper.CleanHu(temphu);

				cmd.nHu = (MajHelper.IsHu(byTempMj, Constants.INVALID_CARD, l_TmpMajSide.hu, temphu, Hua, m_vecResultDingQue[bySeatID])
						? 1 : 0);

				if (m_baoZiTing[bySeatID]) {
					if (IsCanGangInBaoZi(bySeatID, byMoPai, true)) {
						cmd.nGang = 1;
					} else {
						cmd.nGang = 0;
					}
				} else {
					if (IsCanGang(bySeatID, byMoPai, true)) {
						MJ_GANGINFO mjAnGang = MajHelper.IsAnGang(byTempMj, m_vecResultDingQue[bySeatID]);
						MJ_GANGINFO mjZMGang = MajHelper.IsZMGang(byTempMj, l_TmpMajSide.hu);
						cmd.nGang = (mjAnGang.GangStyle + mjZMGang.GangStyle);
					} else {
						cmd.nGang = 0;
					}
				}
				if (l_TmpMajSide.GetChuPaiCount() == 0) {
					int byTingPai[] = new int[42];
					int byEmptyHua[] = new int[7];
					int oldTingPaiCount = MajHelper.GetTingPai(l_TmpMajSide.Maj, l_TmpMajSide.hu, byEmptyHua, byTingPai,
							m_vecResultDingQue[bySeatID]);
					if (m_bTing[bySeatID] == false) {
						cmd.bTing = oldTingPaiCount > 0 ? 1 : 0;
					}
				}
				// if (m_bTing[bySeatID] == false) {
				if (cmd.nGang > 0) {
					m_byRight[byIndex][2] = 1;
				}
				// }
				if (cmd.nHu != 0) {
					m_byRight[byIndex][4] = 1;
				}

			} else {
				cmd.nGang = 0;
				cmd.nHu = 0;
				cmd.byMoPai = 255;
				if (MajHelper.IsHuaPai(byMoPai)) {
					cmd.byMoPai = byMoPai;
				} else {
					cmd.byMoPai = 99;
				}
			}
			// 余牌小于1不能杠
			if (m_daifengpai == 1 && m_MajPaiQiang.GetYuPaiCount() <= 0) {
				cmd.nGang = 0;
			}
			if (m_daifengpai == 0 && m_MajPaiQiangNoFeng.GetYuPaiCount() <= 0) {
				cmd.nGang = 0;
			}
			m_byRight[byIndex][0] = 0;
			m_byRight[byIndex][1] = 0;
			m_byRight[byIndex][2] = cmd.nGang > 0 ? 1 : 0;
			m_byRight[byIndex][3] = cmd.bTing;
			m_byRight[byIndex][4] = cmd.nHu > 0 ? 1 : 0;
			Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);

			Constants.memcpy(cmd.byHandMj, l_MajSide1.Maj, Constants.HAND_MJ_MAX);
			if (true || m_bTing[bySeatID] == false) {// zws true
				if (byIndex != bySeatID) {
					for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
						if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
							cmd.byHandMj[k] = 99;
						}
					}
					cmd.byHandMj[Constants.HAND_MJ_MAX - 1] = 99;
				}
			}

			String sData = cmd.getJsonData();
			SendData(m_pIUserItem[byIndex].dwUserID, sData);

			m_wDealErrorDelay = 0;
		}
		/*
		 * 不自动胡牌zws if (m_bTing[bySeatID]) { if (m_byRight[bySeatID][4] > 0) {
		 * SUBCMD_C_Hu hu = new SUBCMD_C_Hu(); OnUserHu(bySeatID, hu); } }
		 */
		SendYuPai();
		return true;
	}

	boolean OnUserBuHua(int bySeatID) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		m_MajLogic.SetCurrentAction(Constants.ACTION_BU_HUA);
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		int byMoPai = l_MajSide.GetMoPai();
		if (MajHelper.IsHuaPai(byMoPai)) {
			l_MajSide.AddHua(byMoPai);
			l_MajSide.SetMoPai(Constants.INVALID_CARD);
			m_isBusy = true;
			OnUserTouchMj(bySeatID, Constants.ACTION_BU_HUA);
			m_isBusy = false;
			m_wDealErrorDelay = 0;
		} else {

		}
		return true;
	}

	// 用户放弃
	boolean OnUserGiveUp(int bySeatID, SUBCMD_C_Operation Operation) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		// 一轮过，就不让胡了，等下轮
		if (GetActionRight(bySeatID) == Constants.ACTION_HU) {
			isLastHu[bySeatID] = 1;
		}

		m_MajLogic.SetCurrentAction(Constants.ACTION_GIVE_UP);

		CleanTempRight(bySeatID);
		boolean bHasQiangGangHu = HasQiangGangHuRight();
		CleanQiangGangHuRight(bySeatID);
		if (m_bGameStarted) {
			for (int k = 0; k < 4; k++) {
				if (m_bIsHu[k]) {
					int cntHuRight = 0; // 操作者数
					for (int i = 0; i < 4; i++) {
						// 跳过自已,和出牌者
						if (GetActionRight(i) == Constants.ACTION_HU) {

							cntHuRight++;
							break;
						}
					}
					if (cntHuRight == 0) {
						CleanTempAction();

						OnEventGameEnd(bySeatID, Constants.GAME_END_NORMAL);
						m_wDealErrorDelay = 0;
					}
				}
			}
		}

		// 非当前玩家
		if (m_MajLogic.GetMajSide(bySeatID).Maj[Constants.HAND_MJ_MAX - 1] == Constants.INVALID_CARD) {
			int tempRight = 0;
			for (int i = 0; i < 4; i++) {
				if (GetActionRight(i) > tempRight) {
					tempRight = GetActionRight(i);
				}
			}
			if (tempRight > 0) {
				int bySeat1 = MajHelper.GetNextUser(m_MajLogic.GetCurrentUser());
				int bySeat2 = MajHelper.GetNextUser(bySeat1);
				int bySeat3 = MajHelper.GetNextUser(bySeat2);

				int bySeatOrder[] = new int[4];
				bySeatOrder[0] = m_MajLogic.GetCurrentUser();
				bySeatOrder[1] = bySeat1;
				bySeatOrder[2] = bySeat2;
				bySeatOrder[3] = bySeat3;
				for (int i = 0; i < 4; i++) {
					if (bySeatOrder[i] == bySeatID || bySeatOrder[i] == m_MajLogic.GetCurrentUser())
						continue;
					switch (m_tempAction[bySeatOrder[i]].m_ActionRight) {
					case Constants.ACTION_CHI:
						m_isBusy = true;
						OnUserChi(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cChi);
						m_isBusy = false;
						// CleanTempAction();
						break;
					case Constants.ACTION_PENG:
						m_isBusy = true;
						OnUserPeng(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cPeng);
						m_isBusy = false;
						// CleanTempAction();
						break;
					case Constants.ACTION_GANG:
						m_isBusy = true;
						OnUserGang(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cGang);
						m_isBusy = false;
						// CleanTempAction();
						break;
					case Constants.ACTION_HU:
						m_isBusy = true;
						OnUserHu(bySeatOrder[i], m_tempAction[bySeatOrder[i]].m_cHu, 1);
						m_isBusy = false;
						// CleanTempAction();
						break;
					default:
						break;
					}
				}
			} else {
				// 全部人都放弃操作,下家摸牌
				if (bHasQiangGangHu) {
					m_isBusy = true;
					OnUserTouchMj(m_MajLogic.GetCurrentUser(), 0);
					m_isBusy = false;
				} else {
					int byNextUser = MajHelper.GetNextUser(m_MajLogic.GetCurrentUser());
					m_isBusy = true;
					OnUserTouchMj(byNextUser, 0);
					m_isBusy = false;
				}
			}
		} else {
			if (m_baoZiTing[bySeatID]) {
				m_isBusy = true;
				OnUserOutMj(bySeatID, m_MajLogic.GetMajSide(bySeatID).Maj[Constants.HAND_MJ_MAX - 1]);
				m_isBusy = false;
			}
		}

		return true;
	}

	// 用户碰牌
	boolean OnUserPeng(int bySeatID, SUBCMD_C_Operation Peng) {
		if (bySeatID >= 4 || Peng == null) {
			return false;
		}

		{
			MajSide l_MajSide0 = m_MajLogic.GetMajSide(bySeatID);
			System.out.println("[" + m_dwTableID + "] " + "OnUserPeng 2 :" + bySeatID + ":"
					+ IJsonExport.sprintf_INT32(l_MajSide0.Maj, 14));
		}
		int byChuPaiUser = m_MajLogic.GetCurrentUser();
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		MajSide l_ChuPaiMajSide = m_MajLogic.GetMajSide(byChuPaiUser);

		if ((l_MajSide.GetHandMjCount() % 3) != 1) {
			return false;
		}
		m_MajLogic.SetCurrentAction(Constants.ACTION_PENG);
		// 权限效验
		if (GetActionRight(bySeatID) < Constants.ACTION_PENG) {
			return false;
		}
		// 碰牌过，清除
		isLastHu[bySeatID] = 0;

		for (int i = 0; i < 4; i++) {
			m_bDiHu[i] = false;
		}
		int byLastOutMj = m_MajLogic.GetLastOutMj();
		int byLastOutUser = m_MajLogic.GetCurrentUser();

		// 无碰操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			if (i == bySeatID || i == m_MajLogic.GetCurrentUser())
				continue;

			if (GetActionRight(i) > Constants.ACTION_PENG) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_PENG;
				m_tempAction[bySeatID].m_cPeng = Peng;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][1] = 1;
				break;
			} // 碰处理
			else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					CleanTempRight(bySeatID);
					CleanTempAction();
					// 处理碰
					MJ_BLOCK block;
					block = (MJ_BLOCK) MajHelper.Peng(l_MajSide.Maj, m_MajLogic.GetLastOutMj());
					block.origValue = MajHelper.GetRelativeSeat(bySeatID, byLastOutUser);

					int pos = MajHelper.AddBlock(l_MajSide.hu, block);
					if (pos < 4) {
						m_vecChiSide[pos] = byLastOutUser;
					}
					// m_MajLogic.GetMajSide(bySeatID).SortCard();
					MajHelper.SortCard(l_MajSide.Maj, Constants.HAND_MJ_MAX);
					// 发送消息
					SUBCMD_S_Peng cmd = new SUBCMD_S_Peng();
					cmd.block.first = block.first;
					cmd.block.style = block.style;
					cmd.block.origValue = block.origValue;
					cmd.byActionUser = bySeatID;
					cmd.byMj = byLastOutMj;
					cmd.byOutMjUser = byLastOutUser;
					if (true) {
						int byTempMj[] = new int[Constants.HAND_MJ_MAX];
						Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);
						MJ_GANGINFO mjAnGang = MajHelper.IsAnGang(byTempMj, m_vecResultDingQue[bySeatID]);
						MJ_GANGINFO mjZMGang = MajHelper.IsZMGang(byTempMj, l_MajSide.hu);
						cmd.canGang = (mjAnGang.GangStyle + mjZMGang.GangStyle);
						if (cmd.canGang > 0) {
							m_byRight[bySeatID][2] = 1;
						}
					}

					Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
					l_ChuPaiMajSide.BeiChiPai();

					// 当前用户变换
					m_MajLogic.SetCurrentUser(bySeatID);
					for (int j = 0; j < 4; j++) {
						Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
						/*
						 * if (j == bySeatID) { Constants.memcpy(cmd.byHandMj,
						 * l_MajSide.Maj, Constants.HAND_MJ_MAX); } else {
						 * Constants.memcpy(cmd.byHandMj, l_MajSide.Maj,
						 * Constants.HAND_MJ_MAX); for (int k = 0; k <
						 * Constants.HAND_MJ_MAX; k++) { if (cmd.byHandMj[k] !=
						 * Constants.INVALID_CARD) { cmd.byHandMj[k] = 0; } } }
						 */
						Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						if (m_bTing[bySeatID] == false) {
							if (j != bySeatID) {
								for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
									if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
										cmd.byHandMj[k] = 99;
									}
								}
							}
						} else {
							cmd.isMingpai = m_bTing[bySeatID] ? 1 : 0;
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						}

						String sData = cmd.getJsonData();
						SendData(m_pIUserItem[j].dwUserID, sData);
						m_wDealErrorDelay = 0;
					}
					break;
				}
			}
		}
		m_bTestGangShangGang = false;
		SendYuPai();
		return true;
	}

	void renew_kehupai(int bySeatID) {
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

		int testMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(testMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);

		HU testHu = new HU();
		for (int i = 0; i < 4; i++) {
			testHu.block[i].first = l_MajSide.hu.block[i].first;
			testHu.block[i].style = l_MajSide.hu.block[i].style;
		}

		// 可以 暗杠 或者 明杠
		int byTingPai[] = new int[42];
		int byEmptyHua[] = new int[8];
		Constants.memset(byTingPai, Constants.INVALID_CARD, 42);
		Constants.memset(byEmptyHua, Constants.INVALID_CARD, 8);
		Constants.memset(m_byKeHuPai[bySeatID], Constants.INVALID_CARD, 13);
		int tingPaiCount = MajHelper.GetTingPai(testMj, testHu, byEmptyHua, byTingPai, m_vecResultDingQue[bySeatID]);
		if (tingPaiCount > 0) {
			for (int i = 0; i < tingPaiCount; i++) {
				m_byKeHuPai[bySeatID][i] = byTingPai[i];
			}
		}
		SendKeHuPai();
	}

	void SendKeHuPai() {
		SUBCMD_S_KeHuPai cmd = new SUBCMD_S_KeHuPai();
		cmd.byRound = m_byRound;
		boolean bHasTing = false;
		for (int i = 0; i < 4; i++) {
			Constants.memset(cmd.vecKeHuPai[i], Constants.INVALID_CARD, 13);
			if (m_bTing[i]) {
				for (int j = 0; j < 13; j++) {
					cmd.vecKeHuPai[i][j] = m_byKeHuPai[i][j];
				}
				bHasTing = true;
			}
		}
		String sData = cmd.getJsonData();
		if (bHasTing) {
			SendData(Constants.INVALID_CHAIR, sData);
		}
	}

	void Handle_onYiPaoSanXiangHu(int seatId) {
		int huCount = 0;
		for (int i = 0; i < 4; i++) {
			if (this.m_roundHuSeated[i] >= 0) {
				huCount++;
			}
		}
		if (huCount == 0) {
			// 一炮三响的玩家选择了全部过,继续摸牌
			clearRoundHu();
			SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
			m_isBusy = true;
			OnUserGiveUp(seatId, guo);
			m_isBusy = false;
		} else {
			// 这时候一定是顺序胡牌的
			if (huCount == 1)
				m_hasYiPaoSanXiang = false;
			else
				m_hasYiPaoSanXiang = true;
			int huindex = 0;
			for (int i = 0; i < 4; i++) {

				if (this.m_roundHuSeated[i] >= 0) {
					huindex++;
					SUBCMD_C_Hu hu = new SUBCMD_C_Hu();
					OnUserHu(this.m_roundHuSeated[i], hu, huindex == huCount ? 1 : 0);
				}
			}
		}
	}

	boolean OnUserHu(int bySeatID, SUBCMD_C_Hu hu, int huindex) {

		if (bySeatID >= 4)
			return false;
		if (m_bGameStarted == false)
			return false;
		int byLastOutUser = m_MajLogic.GetCurrentUser();
		// 权限校验,这个校验先注释掉了，有个bug，导致用户无法胡牌，一定是自摸的情况下发生的
		/*
		 * if( GetActionRight(bySeatID) < Constants.ACTION_HU &&
		 * m_byRight[bySeatID][4] == 0){ System.out.println("OnUserHu:" +
		 * "1error"); return false; }
		 */
		HU temphu = new HU();
		MajHelper.CleanHu(temphu);
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
		l_MajSide.SortCard();

		int byActivePai = (bySeatID == byLastOutUser) ? l_MajSide.GetMoPai() : m_MajLogic.GetLastOutMj();

		boolean bZiMo = false;
		if (bySeatID == byLastOutUser) // 自摸一台
		{
			bZiMo = true;
		}
		if (IsAllowHu(bySeatID, byActivePai) == false) {
			System.out.println("OnUserHu:" + "2error");
			return false;
		}
		if (MajHelper.IsHu(l_MajSide.Maj, byActivePai, l_MajSide.hu, temphu, l_MajSide.Hua,m_vecResultDingQue[bySeatID])) {
			int byHuSeatID = Constants.INVALID_SEAT_VALUE;
			int bySeat1 = MajHelper.GetNextUser(byLastOutUser);
			int bySeat2 = MajHelper.GetNextUser(bySeat1);
			int bySeat3 = MajHelper.GetNextUser(bySeat2);
			if (bySeatID == bySeat1 || (bySeatID == bySeat2 && GetActionRight(bySeat1) < Constants.ACTION_HU)
					|| (bySeatID == bySeat3 && GetActionRight(bySeat1) < Constants.ACTION_HU
							&& GetActionRight(bySeat2) < Constants.ACTION_HU)) {

				for (int j = 0; j < 4; j++) {
					if (GetActionRight(j) < Constants.ACTION_HU) {
						CleanTempRight(j);
					}
				}
				CleanTempAction();

				CleanTempRight(bySeatID);
				byHuSeatID = bySeatID;
			} else {
				// 无胡操作权限以上的操作
				int userCount = 0; // 操作者数
				for (int i = 0; i < 4; i++) {
					// 跳过自已,和出牌者
					if (i == bySeatID || i == byLastOutUser)
						continue;

					if (GetActionRight(i) == Constants.ACTION_HU) {

						m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_HU;
						m_tempAction[bySeatID].m_cHu = hu;
						break;
					}
					// 胡牌处理

					userCount++;
					CleanTempRight(i);
					if (userCount == 2) {
						CleanTempRight(bySeatID);
						CleanTempAction();
						byHuSeatID = bySeatID;
					}
				}
				if (GetActionRight(bySeatID) == Constants.ACTION_HU) {
					CleanTempRight(bySeatID);
					byHuSeatID = bySeatID;
				}
			}

			CleanTempAction();

			int tmpHandMj[] = new int[Constants.HAND_MJ_MAX];
			Constants.memcpy(tmpHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
			if (byActivePai != Constants.INVALID_CARD) {
				tmpHandMj[Constants.HAND_MJ_MAX - 1] = byActivePai;
			}

			int byTempMj[] = new int[Constants.HAND_MJ_MAX];
			if (temphu.block[0].style == Constants.BLOCK_NULL) {
				Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
				byTempMj[Constants.HAND_MJ_MAX - 1] = byActivePai;
			} else {
				MajHelper.HuToHandMj(byTempMj, temphu);
			}

			MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);

			//////////////////////////// 最后结算////////////////////////////////
			int byHuType[] = new int[60];
			Constants.memset(byHuType, 0, byHuType.length);
			// 先算牌型跟大牌
			// 是豹子牌么
			boolean isBaoZiPaiHu = this.m_baoZiTing[bySeatID];
			// 是包牌么清一色
			boolean isBaoPaiHu = MajHelper.IsPaiXinBaoPai(byTempMj, temphu, byActivePai);
			// 是全幺九么
			boolean isQuanYaoJiu = MajHelper.IsPaiXinQuanYaoJiu(temphu);
			if (this.m_hqDaiDaPai && isQuanYaoJiu) {
				byHuType[Constants.QUAN_YAO_JIU] = 15;
				isBaoPaiHu = MajHelper.IsPaiXinBaoPaiForQuanYaoJiu(byTempMj, temphu, byActivePai);
			}
			// 是清一色么
			boolean isQingYiSe = MajHelper.IsPaiXinQingYiSe(byTempMj, temphu);
			if (this.m_hqDaiDaPai && isQingYiSe) {
				byHuType[Constants.QING_YI_SE] = 5;
			}
			// 是对对胡么
			int duiduihu = MajHelper.IsPaiXinHQDuiDuiHu(byTempMj, byActivePai, temphu);
			if (!isQuanYaoJiu && this.m_hqDaiDaPai && duiduihu > 0) {
				byHuType[Constants.DUI_DUI_HU] = 4;
			}
			// 是混一色么
			boolean isHunYiSe = MajHelper.IsPaiXinHunYiSe(byTempMj, temphu);
			if (this.m_hqDaiDaPai && isHunYiSe) {
				byHuType[Constants.HONG_YI_SE] = 3;
			}
			// 是冲天么
			boolean isChongTian = MajHelper.IsPaiXinChongTian(byTempMj, temphu);
			if (this.m_hqDaiDaPai && isChongTian) {
				byHuType[Constants.CHONG_TIAN] = 2;
			}
			// 四归一
			int siGuiYi = MajHelper.IsPaiXinSiGuiYi(byTempMj, temphu);
			if (this.m_hqDaiDaPai && siGuiYi > 0) {
				byHuType[Constants.SI_GUI_YI] = 1 * siGuiYi;// ==2,表示两个四归一
			}
			// 明杠
			if (this.m_hqMinAnGang) {
				int mingGangNum = m_cntMingGang[bySeatID] + m_cntBuGang[bySeatID];
				byHuType[Constants.MING_GANG_PAI] = mingGangNum;
				int anGangNum = m_cntAnGang[bySeatID];
				byHuType[Constants.AN_GANG_PAI] = anGangNum * 2;
			}
			// 杠上花
			boolean isGangShangHua = (m_MajLogic.GetCurrentAction() == Constants.ACTION_GANG) && bZiMo;
			// 抢杠胡
			boolean isQiangGangHu = !bZiMo && m_bQiangGangHu[bySeatID];
			int qiangGangHuUser = -1;
			if (isQiangGangHu) {
				isGangShangHua = false;
				// byHuType[Constants.QIANG_GANG] = 2;
				for (int i = 0; i < 4; i++) {
					for (int j = 3; j >= 0; j--) {
						if (m_vecGangInfo[i][j].first == byActivePai) {
							// 杠不算了
							qiangGangHuUser = m_vecGangInfo[i][j].GangUser;
							m_vecGangInfo[i][j].reset();
							break;
						}
					}
				}
			}
			m_lastZhuang = m_byZhuang;
			int iFanTotal = 0;
			if (this.m_yunxuzhanzhaung) {
				if (bySeatID == m_byZhuang) {
					iFanTotal += zhuang_num;
					if (zhuang_num > 0) {
						m_vecHuType[bySeatID] += "庄分+" + zhuang_num + " ";
					}
				} else {
					iFanTotal += zhuang_num;
					if (zhuang_num > 0) {
						m_vecHuType[bySeatID] += "庄分+" + zhuang_num + " ";
					}

				}
			}
			// 累计算分 牌型叠加
			for (int i = 0; i < 60; i++) {
				if (byHuType[i] != 0) {
					iFanTotal = iFanTotal + byHuType[i];
				}
			}

			// if (m_fdFen > 0) {
			// if (iFanTotal > m_fdFen) {
			// iFanTotal = m_fdFen;
			// }
			// }

			// m_vecHuType[bySeatID] = "牌型 " + iFanTotal + "分 ";
			if (isQiangGangHu && qiangGangHuUser >= 0) {
				bZiMo = true;
			} else {
				isQiangGangHu = false;
			}
			if (bZiMo) {

				if (isQiangGangHu) {
					m_vecHuType[bySeatID] += "抢杠算自摸  ";
					m_vecHuType[bySeatID] += "底分+1  ";
					byLastOutUser = qiangGangHuUser;
					iFanTotal += 1;
					iFanTotal *= 2;

				} else if (isGangShangHua) {
					iFanTotal += 1;
					m_vecHuType[bySeatID] += "底分+1  ";
					if (m_vecHuType[bySeatID].indexOf("平胡+1 ") == -1)
						m_vecHuType[bySeatID] += "平胡+1 ";
				} else if (isBaoZiPaiHu) {
					iFanTotal += 1;
					iFanTotal *= 2;
					m_vecHuType[bySeatID] += "底分+1  ";
					m_vecHuType[bySeatID] += "自摸翻倍  ";
				} else if (!m_bTianHu) {
					m_vecHuType[bySeatID] += "底分+1  ";
					m_vecHuType[bySeatID] += "自摸翻倍  ";
					iFanTotal += 1;
					iFanTotal *= 2;
				} else {
					iFanTotal *= 2;
				}
				m_lostSeatId = -1;
			} else {
				if (m_vecHuType[bySeatID].indexOf("平胡+1") == -1)
					m_vecHuType[bySeatID] += "平胡+1 ";
				if (m_bQiangGangHu[bySeatID]) {
					if (m_vecHuType[bySeatID].indexOf("抢杠开花") == -1)
						m_vecHuType[bySeatID] += "抢杠开花  ";
					m_vecHuType[byLastOutUser] += "被抢杠 ";
				} else {
					if (LastOutNum == 0)
						m_vecHuType[byLastOutUser] += "放铳翻倍 ";
				}
				m_lostSeatId = byLastOutUser;
			}
			m_vecHuType[bySeatID] += HuToString(byHuType);
			int curDiFen = m_diFen;
			if (bZiMo) {// 赢家+3，其余玩家各-1
				for (int k = 0; k < 4; k++) {
					if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
						// 抢杠自摸的话，点炮的x2
						if (isQiangGangHu && k == byLastOutUser) {
							roundScore[k] -= 2 + iFanTotal * curDiFen;
						} else {
							roundScore[k] = -iFanTotal * curDiFen;
						}
					}
				}
				// 是包牌情况下，并且抢杠自摸
				if (isBaoPaiHu && isQiangGangHu) {
					for (int k = 0; k < 4; k++) {
						if (k != bySeatID && m_pIUserItem[k].dwUserID > 0 && k != byLastOutUser) {
							roundScore[byLastOutUser] += roundScore[k];
							roundScore[k] = 0;
						}
					}
					m_vecHuType[bySeatID] += "包牌赢  ";
					m_vecHuType[byLastOutUser] += "包牌放铳全包  ";
				}
				// 抢杠算自摸，并且还是豹子
				if (isQiangGangHu && m_baoZiTing[byLastOutUser]) {
					roundScore[byLastOutUser] *= 2;
					m_vecHuType[byLastOutUser] += "豹子点炮x2  ";
				}
				// 豹子牌每家x2
				if (this.m_hqTianLuoDiHu && isBaoZiPaiHu) {
					for (int k = 0; k < 4; k++) {
						if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
							roundScore[k] *= 2;
						}
					}
					m_vecHuType[bySeatID] += "豹子x2 ";
				}
				// 是杠上开花
				// 杠的计算需要x4,单独计算分倍与杠
				this.m_isHuGangShangHua = isGangShangHua;
				// this.m_isHUSeatId = bySeatID;
				if (this.m_hqGangHoux4 && this.m_isHuGangShangHua) {
					for (int k = 0; k < 4; k++) {
						if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
							roundScore[k] *= 4;
						}
					}
				}
				if (m_bTianHu) {
					// 天胡不翻倍，放到这里
					for (int k = 0; k < 4; k++) {
						if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
							roundScore[k] -= 10;// 10天胡分数
						}
					}
					m_vecHuType[bySeatID] += "天胡+10  ";
				}
				// 加给赢家
				for (int k = 0; k < 4; k++) {
					if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
						roundScore[bySeatID] += 0 - roundScore[k];
					}
				}
				// 赢家坐庄
			} else {// 放统计算,霍邱玩法，点炮的双倍，闲家一倍
				LastOutNum++;
				int LastOutUserScore = 0;
				if (LastOutNum == 1) {
					// 这是第一个真正胡的玩家
					if (isBaoPaiHu) {
						// 是包牌，点炮者自己出4
						if (byLastOutUser < 4 && byLastOutUser != bySeatID
								&& m_pIUserItem[byLastOutUser].dwUserID > 0) {
							LastOutUserScore = (1 + iFanTotal) * curDiFen;
							if (m_baoZiTing[byLastOutUser]) {
								m_vecHuType[byLastOutUser] += "豹子放铳x2  ";
								LastOutUserScore *= 6;// 豹子乘4 + 包两家
							} else {
								LastOutUserScore *= 4;// 放铳乘2 + 包两家
							}

							roundScore[byLastOutUser] += -LastOutUserScore;
							m_vecHuType[bySeatID] += "包牌赢  ";
							m_vecHuType[byLastOutUser] += "包牌放铳全包  ";
						}
					} else {
						// 豹子点炮x4,闲家x2
						if (isBaoZiPaiHu) {
							m_vecHuType[bySeatID] += "地胡x2 ";
							for (int k = 0; k < 4; k++) {
								if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
									if (m_baoZiTing[byLastOutUser]) {
										// 是豹子点的炮
										if (k != byLastOutUser && !this.m_hqShuiDaShuiBao) {
											// 闲家
											int score = (1 + iFanTotal) * curDiFen;
											score *= 2;
											roundScore[k] += -score;
										} else if (k == byLastOutUser) {
											// 点炮
											int score = (1 + iFanTotal) * curDiFen;
											score *= 4;
											score *= 2;
											roundScore[k] += -score;
											m_vecHuType[byLastOutUser] += "地胡放铳翻倍  ";
										}
									} else {
										// 非豹子点炮
										if (k != byLastOutUser && !this.m_hqShuiDaShuiBao) {
											// 闲家
											int score = (1 + iFanTotal) * curDiFen;
											score *= 2;
											roundScore[k] += -score;
										} else if (k == byLastOutUser) {
											// 点炮
											int score = (1 + iFanTotal) * curDiFen;
											score *= 4;
											roundScore[k] += -score;
											m_vecHuType[byLastOutUser] += "地胡放铳翻倍  ";
										}
									}
								}
							}
						} else {
							// 普通胡牌，点炮出2，闲家出1
							for (int k = 0; k < 4; k++) {
								if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
									if (m_baoZiTing[byLastOutUser]) {
										if (k != byLastOutUser && !this.m_hqShuiDaShuiBao) {
											// 闲家
											int score = (1 + iFanTotal) * curDiFen;
											roundScore[k] += -score;
										} else if (k == byLastOutUser) {
											// 点炮
											int score = (1 + iFanTotal) * 2;
											score = (4 + iFanTotal) * curDiFen;
											roundScore[k] += -score;
											m_vecHuType[byLastOutUser] += "地胡放铳翻倍  ";
										}
									} else {
										if (k != byLastOutUser && !this.m_hqShuiDaShuiBao) {
											// 闲家
											int score = (1 + iFanTotal) * curDiFen;
											roundScore[k] += -score;
										} else if (k == byLastOutUser) {
											// 点炮
											int score = (1 + iFanTotal) * 2;
											roundScore[k] += -score;
										}
									}
								}
							}
						}
					}

					// 加给赢家
					for (int k = 0; k < 4; k++) {
						if (k != bySeatID && m_pIUserItem[k].dwUserID > 0) {
							roundScore[bySeatID] += 0 - roundScore[k];
						}
					}
				} else {
					// 一炮多响情况别的玩家，不是真胡(不用算分),点炮的给这个出2
					if (this.m_hqYiPaoSanXiang && byLastOutUser < 4 && byLastOutUser != bySeatID
							&& m_pIUserItem[byLastOutUser].dwUserID > 0) {
						iFanTotal += 1;
						if (isBaoZiPaiHu) {
							m_vecHuType[bySeatID] += "地胡x2  ";
							iFanTotal *= 2;
						}
						int score = -iFanTotal * 2;
						roundScore[byLastOutUser] += score;
						roundScore[bySeatID] += -score;
						if (m_vecHuType[byLastOutUser].indexOf("一炮多响") == -1)
							m_vecHuType[byLastOutUser] += "一炮多响 ";
						// 一炮三响的当庄
					}
				}
			}

			if ((m_hasYiPaoSanXiang && LastOutNum == 1) || huindex == 0) {
				return true;
			}
			// for (int k = 0; k < 4; k++) {
			// m_vecRoundScore[k] = roundScore[k];
			// m_vecResultScore[k] += roundScore[k];
			// if (LastOutNum >= 2) {
			// m_vecResultScore[k] -= LastOutOld[k];
			// }
			// }
			//
			// for (int k = 0; k < 4; k++) {
			// m_pIUserItem[k].lUserScore += roundScore[k];
			// if (LastOutNum >= 2) {
			// m_pIUserItem[k].lUserScore -= LastOutOld[k];
			// }
			// if (roundScore[k] > 0) {
			// m_vecWinScore[k] += roundScore[k];
			// } else {
			// m_vecLoseScore[k] += roundScore[k];
			// if (LastOutNum >= 2) {
			// m_vecLoseScore[k] -= LastOutOld[k];
			// }
			// }
			// }
			for (int k = 0; k < 4; k++) {
				roundScore[k] += m_vecGangScore[k];
			}
			for (int k = 0; k < 4; k++) {

				m_vecRoundScore[k] = roundScore[k];
				m_vecResultScore[k] += roundScore[k];
			}

			for (int k = 0; k < 4; k++) {
				m_pIUserItem[k].lUserScore += roundScore[k];

				if (roundScore[k] > 0) {
					m_vecWinScore[k] += roundScore[k];
				} else {
					m_vecLoseScore[k] += roundScore[k];
				}
			}
			m_vecZiMo[bySeatID] = bZiMo ? 1 : 0;
			m_kReport[bySeatID].cntHu++;
			if (bZiMo) {
				m_kReport[bySeatID].cntZiMo++;
			} else {
				m_kReport[byLastOutUser].cntDianPao++;
			}
			m_wDealErrorDelay = 0;
			m_bIsHu[bySeatID] = true;
			int cntHuRight = 0; // 操作者数
			for (int i = 0; i < 4; i++) {
				// 跳过自已,和出牌者
				if (i == bySeatID || i == byLastOutUser)
					continue;

				if (GetActionRight(i) == Constants.ACTION_HU) {
					cntHuRight++;
					break;
				}
			}

			l_MajSide.SetMoPai(byActivePai);

			if (cntHuRight == 0) {
				CleanTempAction();

				AdjustSuanFen();
			}

			if (this.m_hqGangHoux4 && this.m_isHuGangShangHua) {
				m_vecHuType[bySeatID] += "杠后一乘四  ";
			}

			if (bySeatID == this.m_winSeatId && this.m_hqDaiDaPai)
				m_vecHuType[bySeatID] += "带大牌 ";
			else if (bySeatID == this.m_winSeatId && !this.m_hqDaiDaPai)
				m_vecHuType[bySeatID] += "不带大牌 ";

			{
				SUBCMD_S_HU cmd = new SUBCMD_S_HU();

				cmd.byWinner = bySeatID;
				if (bySeatID == byLastOutUser) {
					cmd.byFangQiang = Constants.INVALID_CHAIR;
				} else {
					cmd.byFangQiang = byLastOutUser;
				}
				cmd.byHuMj = byActivePai;
				for (int k = 0; k < 4; k++) {
					cmd.winScore[k] = roundScore[k];
					cmd.resultScore[k] = m_pIUserItem[k].lUserScore;
				}
				SendData(Constants.INVALID_CHAIR, cmd.getJsonData());
			}

			if (cntHuRight == 0) {
				OnEventGameEnd(bySeatID, Constants.GAME_END_NORMAL);
			}
			for (int i = 0; i < 4; i++) {
				// LastOutOld[i] = roundScore[i]; zws 不用这个
			}
		}

		if (this.m_yunxuzhanzhaung) {
			if (bySeatID == m_byZhuang) {
				zhuang_num++;
				m_byLianZhuang++;
			} else {
				zhuang_num = 0;
				m_byLianZhuang = 1;
			}
			m_byZhuang = bySeatID;

		} else {
			// 判断坐庄的情况
			if (bySeatID == m_byZhuang) {
				zhuang_num++;
				m_byZhuang = bySeatID;
			} else {
				m_byZhuang = (m_byZhuang + 1) % 4;
				zhuang_num = 0;
			}
		}
		if (LastOutNum > 1) {
			this.m_byZhuang = byLastOutUser;
			zhuang_num = 0;
		}
		SendYuPai();
		return true;

	}

	void AdjustSuanFen() {
		if (false && this.m_hqMinAnGang) {
			// 不在用这里了
			for (int i = 0; i < 4; i++) {
				int power = this.m_diFen;
				if (this.IsInRoundHu(i) && this.m_hqGangHoux4 && this.m_isHuGangShangHua)
					power *= 4;
				else if (i == m_winSeatId && this.m_hqGangHoux4 && this.m_isHuGangShangHua)
					power *= 4;
				else if (i == m_winSeatId)
					power = this.m_diFen;
				else if (this.IsInRoundHu(i))
					power = this.m_diFen;
				else
					continue;// 不胡牌的玩家杠全部作废
				if (m_cntAnGang[i] > 0) {
					m_vecHuType[i] += "暗杠+" + 2 * m_cntAnGang[i] + "分  ";
				}
				if (m_cntMingGang[i] > 0) {
					m_vecHuType[i] += "明杠+" + 1 * m_cntMingGang[i] + "分  ";
				}
				if (m_cntBuGang[i] > 0) {
					m_vecHuType[i] += "补杠+" + 1 * m_cntBuGang[i] + "分  ";
				}
				/*
				 * if (m_cntDianGang[i] > 0 ) { m_vecHuType[i] += "点杠-" +
				 * m_cntDianGang[i] + "分  "; }
				 */
				// 霍邱明杠大家都出1，暗杠大家都出2
				for (int j = 0; j < 4; j++) {
					if (m_vecGangInfo[i][j].style > 0) {
						if (m_vecGangInfo[i][j].style == Constants.BLOCK_GANG
								|| m_vecGangInfo[i][j].style == Constants.BLOCK_BU_GANG) {
							int beishu = 0;
							int k1 = MajHelper.GetNextUser(i);
							if (k1 == this.m_lostSeatId) {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							} else {
								beishu += 1;
								m_vecGangScore[k1] -= power;
							}
							k1 = MajHelper.GetNextUser(k1);
							if (k1 == this.m_lostSeatId) {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							} else {
								beishu += 1;
								m_vecGangScore[k1] -= power;
							}
							k1 = MajHelper.GetNextUser(k1);
							if (k1 == this.m_lostSeatId) {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							} else {
								beishu += 1;
								m_vecGangScore[k1] -= power;
							}
							m_vecGangScore[i] += beishu * power;
						}
						if (m_vecGangInfo[i][j].style == Constants.BLOCK_AN_GANG) {
							int beishu = 0;
							int k1 = MajHelper.GetNextUser(i);
							if (k1 == this.m_lostSeatId) {
								beishu += 4;
								m_vecGangScore[k1] -= 4 * power;
							} else {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							}
							k1 = MajHelper.GetNextUser(k1);
							if (k1 == this.m_lostSeatId) {
								beishu += 4;
								m_vecGangScore[k1] -= 4 * power;
							} else {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							}
							k1 = MajHelper.GetNextUser(k1);
							if (k1 == this.m_lostSeatId) {
								beishu += 4;
								m_vecGangScore[k1] -= 4 * power;
							} else {
								beishu += 2;
								m_vecGangScore[k1] -= 2 * power;
							}
							m_vecGangScore[i] += beishu * power;
						}
					}
				}
			}
		}
		for (int i = 0; i < 4; i++) {
			m_vecRoundScore[i] += m_vecGangScore[i];
			m_pIUserItem[i].lUserScore += m_vecGangScore[i];
			m_vecResultScore[i] += m_vecGangScore[i];
			if (m_vecHuType[i].indexOf("总分") != -1) {
				String total = "总牌型" + m_vecRoundScore[i];
				String type = m_vecHuType[i].replaceAll("总分", total);
				m_vecHuType[i] = type;
			}

		}
	}

	// 用户吃牌
	boolean OnUserChi(int bySeatID, SUBCMD_C_Chi Chi) {
		if (bySeatID >= 4 || Chi == null) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);

		if ((l_MajSide.GetHandMjCount() % 3) != 1) {
			return false;
		}

		m_MajLogic.SetCurrentAction(0);
		// 设置变量
		// SUBCMD_C_Chi Chi = ( SUBCMD_C_Chi * )pDataBuffer;
		if (GetActionRight(bySeatID) < Constants.ACTION_CHI) {
			return false;
		}
		for (int i = 0; i < 4; i++) {
			m_bDiHu[i] = false;
		}
		int byLastOutMj = m_MajLogic.GetLastOutMj();

		int byLastOutUser = m_MajLogic.GetCurrentUser();
		// 无碰操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			if (i == bySeatID || i == m_MajLogic.GetCurrentUser())
				continue;

			if (GetActionRight(i) > Constants.ACTION_CHI) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_CHI;
				m_tempAction[bySeatID].m_cChi = Chi;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][0] = 1;
				break;
			} // 吃处理
			else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					CleanTempRight(bySeatID);
					// 处理吃

					MJ_BLOCK block;
					block = (MJ_BLOCK) MajHelper.Chi(l_MajSide.Maj, m_MajLogic.GetLastOutMj(), Chi.nChiType);
					int pos = MajHelper.AddBlock(l_MajSide.hu, block);
					m_vecChiSide[pos] = byLastOutUser;
					l_MajSide.SortCard();

					// 发送消息
					SUBCMD_S_Chi cmd = new SUBCMD_S_Chi();
					Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
					cmd.block = block;
					cmd.byActionUser = bySeatID;
					cmd.nChiType = Chi.nChiType;
					cmd.byMj = byLastOutMj;
					// 上次操作玩家-出牌者
					cmd.byOutMjUser = m_MajLogic.GetCurrentUser();
					if (true) {
						int byTempMj[] = new int[Constants.HAND_MJ_MAX];
						Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX);
						MJ_GANGINFO mjAnGang = MajHelper.IsAnGang(byTempMj, m_vecResultDingQue[bySeatID]);
						MJ_GANGINFO mjZMGang = MajHelper.IsZMGang(byTempMj, l_MajSide.hu);
						cmd.canGang = (mjAnGang.GangStyle + mjZMGang.GangStyle);
						if (cmd.canGang > 0) {
							m_byRight[bySeatID][2] = 1;
						}
					}
					m_MajLogic.GetMajSide(m_MajLogic.GetCurrentUser()).BeiChiPai();
					// 当前用户变换
					m_MajLogic.SetCurrentUser(bySeatID);

					for (int j = 0; j < 4; j++) {
						Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);

						/*
						 * if (j == bySeatID) { Constants.memcpy(cmd.byHandMj,
						 * l_MajSide.Maj, Constants.HAND_MJ_MAX); } else {
						 * Constants.memcpy(cmd.byHandMj, l_MajSide.Maj,
						 * Constants.HAND_MJ_MAX); for (int k = 0; k <
						 * Constants.HAND_MJ_MAX; k++) { if (cmd.byHandMj[k] !=
						 * Constants.INVALID_CARD) { cmd.byHandMj[k] = 0; } } }
						 */
						Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						if (m_bTing[bySeatID] == false) {
							if (j != bySeatID) {
								for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
									if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
										cmd.byHandMj[k] = 99;
									}
								}
							}
						} else {
							cmd.isMingpai = m_bTing[bySeatID] ? 1 : 0;
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
						}

						String sData = cmd.getJsonData();
						SendData(m_pIUserItem[j].dwUserID, sData);
						m_wDealErrorDelay = 0;
					}
					CleanTempAction();
				}
			}
		}
		m_bTestGangShangGang = false;
		SendYuPai();
		return true;
	}

	// 用户杠牌
	boolean OnUserGang(int bySeatID, SUBCMD_C_Gang Gang) {
		/* printf("GANG[%d]\n",bySeatID); */
		if (bySeatID >= 4 || Gang == null) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		// SUBCMD_C_Gang Gang = ( SUBCMD_C_Gang * )pDataBuffer;
		// 权限效验
		// 这边是绕开了一个bug，在豹子牌下面，无法暗杠，奇怪，权限被清除了
		if (Gang.nGangMode != 2 && Gang.nGangMode != 4 && GetActionRight(bySeatID) < Constants.ACTION_GANG) {
			return false;
		}

		// 杠牌过，清除
		isLastHu[bySeatID] = 0;

		int byLastOutUser = m_MajLogic.GetCurrentUser();

		// 无杠操作权限以上的操作
		int userCount = 0; // 操作者数
		for (int i = 0; i < 4; i++) {
			// 跳过自已,和出牌者
			if (i == bySeatID || i == m_MajLogic.GetCurrentUser())
				continue;

			if (GetActionRight(i) > Constants.ACTION_GANG) {
				m_tempAction[bySeatID].m_ActionRight = Constants.ACTION_GANG;
				m_tempAction[bySeatID].m_cGang = Gang;
				CleanTempRight(bySeatID);
				m_byRight[bySeatID][2] = 1;
				break;
			}

			// 杠处理
			else {
				userCount++;
				CleanTempRight(i);
				if (userCount == 2) {
					switch (Gang.nGangMode) {
					case 1: // 普通杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						MJ_BLOCK block;
						block = (MJ_BLOCK) MajHelper.MGang(l_MajSide.Maj, m_MajLogic.GetLastOutMj(),
								m_MajLogic.GetCurrentUser());
						block.style = Constants.BLOCK_GANG;

						if (bySeatID != m_MajLogic.GetCurrentUser()) {
							block.OutUserGang = m_MajLogic.GetCurrentUser();
						}
						int pos = MajHelper.AddBlock(l_MajSide.hu, block);
						if (pos < 4) {
							m_vecChiSide[pos] = byLastOutUser;
						}
						m_kReport[bySeatID].cntGang++;
						if (pos < 4) {
							if (m_bTestGangShangGang) {
								m_cntLianGang++;
							}
							int power = (int) Math.pow(2, m_cntLianGang);

							m_vecGangInfo[bySeatID][pos].first = Gang.byGangMj;
							m_vecGangInfo[bySeatID][pos].style = Constants.BLOCK_GANG;
							m_vecGangInfo[bySeatID][pos].GangUser = byLastOutUser;
							m_vecGangInfo[bySeatID][pos].cntLianGang = m_cntLianGang;

							m_cntMingGang[bySeatID] += 1;
							m_cntDianGang[byLastOutUser] += 1;

						}

						m_bTestGangShangGang = true;
						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						// 发送杠牌消息
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();
						cmd.byActionUser = bySeatID;
						cmd.byOutMjUser = byLastOutUser;
						cmd.byMj = block.first;
						cmd.block = block;
						cmd.gangType = 1;
						cmd.byBuMj = 255;

						cmd.bZiMoGang = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));

						CleanTempAction();

						m_MajLogic.GetMajSide(m_MajLogic.GetCurrentUser()).BeiChiPai();
						// 当前用户变换
						m_MajLogic.SetCurrentUser(bySeatID);

						for (int j = 0; j < 4; j++) {
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							if (m_bTing[bySeatID] == false) {
								if (j != bySeatID) {
									for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
										if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
											cmd.byHandMj[k] = 99;
										}
									}
								}
							} else {
								cmd.isMingpai = m_bTing[bySeatID] ? 1 : 0;
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							}

							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[j].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}
						m_isBusy = true;
						// 杠牌者摸牌
						OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);
						m_isBusy = false;
					}
						break;
					case 2: // 补杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						int byMoPai = l_MajSide.GetMoPai();
						MajHelper.ZMGang(l_MajSide.Maj, l_MajSide.hu, Gang.byGangMj);
						int pos = 255;
						for (int k = 0; k < (Constants.HAND_MJ_MAX - 2) / 3; k++) {
							if (l_MajSide.hu.block[k].first == Gang.byGangMj) {
								pos = k;
								break;
							}
						}
						if (pos < 4) {
							if (m_bTestGangShangGang && Gang.byGangMj == byMoPai) {
								m_cntLianGang++;
							}
							int power = (int) Math.pow(2, m_cntLianGang);

							m_vecGangInfo[bySeatID][pos].first = Gang.byGangMj;
							m_vecGangInfo[bySeatID][pos].style = Constants.BLOCK_BU_GANG;
							m_vecGangInfo[bySeatID][pos].GangUser = bySeatID;
							m_vecGangInfo[bySeatID][pos].cntLianGang = m_cntLianGang;

						}

						m_bTestGangShangGang = true;
						m_MajLogic.GetMajSide(bySeatID).SortCard(Constants.HAND_MJ_MAX);

						m_cntBuGang[bySeatID] += 1;
						m_kReport[bySeatID].cntGang++;

						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						MJ_BLOCK block = new MJ_BLOCK();
						block.style = Constants.BLOCK_GANG;
						block.first = Gang.byGangMj;
						// 发送杠牌消息
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();
						cmd.byActionUser = bySeatID;
						cmd.byOutMjUser = m_MajLogic.GetCurrentUser();
						cmd.block = block;
						cmd.gangType = 2;
						cmd.byMj = Gang.byGangMj;
						cmd.byBuMj = 255;
						cmd.bTing = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));

						m_MajLogic.SetCurrentUser(bySeatID);
						for (int j = 0; j < 4; j++) {
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							if (m_bTing[bySeatID] == false || bySeatID >= 0) {
								if (j != bySeatID) {
									for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
										if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
											cmd.byHandMj[k] = 99;
										}
									}
									MajSide l_TmpMajSide = m_MajLogic.GetMajSide(j);
									m_MajLogic.SetLastOutMj(Gang.byGangMj);
									if (IsAllowHu(j, Gang.byGangMj)) {
										m_byRight[j][4] = (MajHelper.IsHu(l_TmpMajSide.Maj, Gang.byGangMj,
												l_TmpMajSide.hu, new HU(), l_TmpMajSide.Hua, m_vecResultDingQue[bySeatID]) ? 1 : 0);
									}

									m_bQiangGangHu[j] = m_byRight[j][4] == 0 ? false : true;
									cmd.bHu[j] = m_byRight[j][4];
									cmd.bQiangHu = m_byRight[j][4] == 0 ? 0 : 1;
								}
							} else {
								cmd.isMingpai = m_bTing[bySeatID] ? 1 : 0;
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							}

							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[j].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}
						CleanTempAction();

						if (HasQiangGangHuRight() == false) {
							// 当前用户变换

							// 杠牌者摸牌
							m_isBusy = true;
							OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);
							m_isBusy = false;
						}
					}
						break;
					case 4: // 暗杠
					{
						CleanTempRight(bySeatID);
						MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
						MJ_BLOCK block;
						block = (MJ_BLOCK) MajHelper.AnGang(l_MajSide.Maj, Gang.byGangMj);
						int pos = MajHelper.AddBlock(l_MajSide.hu, block);
						if (pos < 4) {
							if (m_bTestGangShangGang) {
								m_cntLianGang++;
							}
							int power = (int) Math.pow(2, m_cntLianGang);

							m_vecGangInfo[bySeatID][pos].first = Gang.byGangMj;
							m_vecGangInfo[bySeatID][pos].style = Constants.BLOCK_AN_GANG;
							m_vecGangInfo[bySeatID][pos].GangUser = bySeatID;
							m_vecGangInfo[bySeatID][pos].cntLianGang = m_cntLianGang;

						}
						m_bTestGangShangGang = true;
						m_MajLogic.GetMajSide(bySeatID).SortCard(Constants.HAND_MJ_MAX);

						m_cntAnGang[bySeatID] += 1;
						m_kReport[bySeatID].cntAnGang++;

						m_MajLogic.SetCurrentAction(Constants.ACTION_GANG);
						// 消息处理
						SUBCMD_S_Gang cmd = new SUBCMD_S_Gang();
						cmd.block = block;
						cmd.byActionUser = bySeatID;
						cmd.gangType = 4;
						cmd.byMj = block.first;
						cmd.byBuMj = 255;
						cmd.bZiMoGang = 0;
						cmd.bTing = 0;
						Constants.memset(cmd.bHu, 0, Constants.sizeof(cmd.bHu));
						for (int j = 0; j < 4; j++) {
							Constants.memset(cmd.byHandMj, Constants.INVALID_CARD, Constants.HAND_MJ_MAX);
							Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							if (m_bTing[bySeatID] == false) {
								if (j != bySeatID) {
									for (int k = 0; k < Constants.HAND_MJ_MAX; k++) {
										if (MajHelper.IsWTSZ(cmd.byHandMj[k])) {
											cmd.byHandMj[k] = 99;
										}
									}
								}
							} else {
								cmd.isMingpai = m_bTing[bySeatID] ? 1 : 0;
								Constants.memcpy(cmd.byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
							}

							String sData = cmd.getJsonData();
							SendData(m_pIUserItem[j].dwUserID, sData);
							m_wDealErrorDelay = 0;
						}
						CleanTempAction();
						// 发送消息

						// 杠牌者摸牌
						m_isBusy = true;
						OnUserTouchMj(bySeatID, Constants.ACTION_GANG_BUPAI);
						m_isBusy = false;

					}
						break;
					}
				}
			}
		}
		{
			MajSide l_MajSide0 = m_MajLogic.GetMajSide(0);
			System.out.println("OnUserGang 2:" + 0 + ":" + IJsonExport.sprintf_INT32(l_MajSide0.Maj, 14));
		}

		SendYuPai();
		return true;
	}

	boolean OnUserTing(int bySeatID) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		if (m_byChuPaiCount[bySeatID] == 0) {
			m_bDiTing[bySeatID] = true;
		}
		if (m_byChuPaiCount[bySeatID] == 0) {
			m_baoZiTing[bySeatID] = true;
		}

		m_MajLogic.SetCurrentAction(Constants.ACTION_TING);
		SUBCMD_S_Ting cmd = new SUBCMD_S_Ting();
		cmd.byActionUser = bySeatID;

		m_bTing[bySeatID] = true;
		m_MajLogic.GetMajSide(bySeatID).byTing = 1;

		String sData = cmd.getJsonData();
		SendData(m_pIUserItem[bySeatID].dwUserID, sData);
		m_wDealErrorDelay = 0;
		return false;
	}

	String HuToString(int byHuType[]) {
		String strHuType = "";
		if (byHuType[Constants.QING_YI_SE] != 0 && byHuType[Constants.DUI_DUI_HU] != 0) {
			int fan = byHuType[Constants.QING_YI_SE] + byHuType[Constants.DUI_DUI_HU];
			strHuType += "清一色对对胡 +" + fan + "分  ";
			byHuType[Constants.QING_YI_SE] = 0;
			byHuType[Constants.DUI_DUI_HU] = 0;
		}
		if (byHuType[Constants.HONG_YI_SE] != 0 && byHuType[Constants.DUI_DUI_HU] != 0) {
			int fan = byHuType[Constants.HONG_YI_SE] + byHuType[Constants.DUI_DUI_HU];
			strHuType += "红一色对对胡+ " + fan + "分  ";
			byHuType[Constants.HONG_YI_SE] = 0;
			byHuType[Constants.DUI_DUI_HU] = 0;
		}
		for (int i = 0; i < byHuType.length; i++) {
			if (byHuType[i] != 0) {
				switch (i) {
				case Constants.TUI_DAO_HU:
					if (strHuType.indexOf("平牌+1分") == -1)
						strHuType += "平牌+" + byHuType[i] + "分  ";
					break;
				case Constants.GANG_KAI:
					if (strHuType.indexOf("杠上开花") == -1)
						strHuType += "杠上开花+" + byHuType[i] + "分  ";
					break;
				case Constants.GANG_SHANG_PAO:
					strHuType += "杠上炮 " + byHuType[i] + "分 ";
					break;
				case Constants.QIANG_GANG:
					strHuType += "抢杠胡 " + byHuType[i] + "分 ";
					break;
				case Constants.QI_DUI_ZI:
					strHuType += "七对子  " + byHuType[i] + "分 ";
					break;
				case Constants.HAO_HUA_QI_DUI_ZI:
					strHuType += "龙七对子  " + byHuType[i] + "分 ";
					break;
				case Constants.SHUANG_HAO_HUA_QI_DUI_ZI:
					strHuType += "超豪华七对子  " + byHuType[i] + "分 ";
					break;
				case Constants.SAN_HAO_HUA_QI_DUI_ZI:
					strHuType += "超超豪华七对子  " + byHuType[i] + "分 ";
					break;
				case Constants.PENG_PENG_HU:
					strHuType += "对对胡  " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE:
					strHuType += "清一色+" + byHuType[i] + "分  ";
					break;
				case Constants.XIAO_SAN_YUAN:
					strHuType += "小三元  " + byHuType[i] + "分 ";
					break;
				case Constants.TIAN_HU:
					strHuType += "天落+" + byHuType[i] + "分  ";
					break;
				case Constants.DI_HU:
					strHuType += "地胡  " + byHuType[i] + "分 ";
					break;
				case Constants.REN_HU:
					strHuType += "人胡  " + byHuType[i] + "分 ";
					break;
				case Constants.TIAN_TING:
					strHuType += "天听  " + byHuType[i] + "分 ";
					break;
				case Constants.DA_SAN_YUAN:
					strHuType += "大三元  " + byHuType[i] + "分 ";
					break;
				case Constants.HAI_DI_LAO_YUE:
					strHuType += "海底捞" + byHuType[i] + "分 ";
					break;
				case Constants.HAI_DI_LAO_YUE_PAO:
					strHuType += "海底炮" + byHuType[i] + "分 ";
					break;
				/*
				 * case Constants.MINGPAI: strHuType += "亮牌  " + byHuType[i] +
				 * "分 "; break;
				 */
				case Constants.MING_GANG_PAI:
					strHuType += "明杠+" + byHuType[i] + "分  ";
					break;
				case Constants.AN_GANG_PAI:
					strHuType += "暗杠+" + byHuType[i] + "分  ";
					break;
				case Constants.DAXUESHI_PAI:
					strHuType += "大学士清场   " + byHuType[i] + "分 ";
					break;
				case Constants.SHOU_ZHUA_YI:
					strHuType += "手抓一   " + byHuType[i] + "分 ";
					break;
				case Constants.KA_WU_XING:
					strHuType += "卡五星   " + byHuType[i] + "分 ";
					break;
				case Constants.MING_SI_GUI:
					strHuType += "明四归   " + byHuType[i] + "分 ";
					break;
				case Constants.AN_SI_GUI:
					strHuType += "暗四归   " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_PENG_PENG_HU:
					strHuType += "清一色碰碰胡   " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_QI_DUI_ZI:
					strHuType += "清一色七对   " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_SHOU_ZHUA_YI:
					strHuType += "清一色手抓一   " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_KA_WU_XING:
					strHuType += "清一色卡五星   " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_MING_SE_GUI:
					strHuType += "清一色明四归    " + byHuType[i] + "分 ";
					break;
				case Constants.QING_YI_SE_AN_SE_GUI:
					strHuType += "清一色暗四归   " + byHuType[i] + "分 ";
					break;
				// HQ
				case Constants.DUI_DUI_HU:
					strHuType += "对对胡+" + byHuType[i] + "分  ";
					break;
				case Constants.QUAN_YAO_JIU:
					strHuType += "全幺九+" + byHuType[i] + "分  ";
					break;
				case Constants.CHONG_TIAN:
					strHuType += "冲天+" + byHuType[i] + "分  ";
					break;
				case Constants.HONG_YI_SE:
					strHuType += "红一色+" + byHuType[i] + "分  ";
					break;
				case Constants.SI_GUI_YI:
					strHuType += "四归一+" + byHuType[i] + "分  ";
					break;
				}
			}
		}
		return strHuType;
	}

	void OnEventGameStart() {
		Init(Constants.INIT_NEWROUND);
		OnDingQueStart();
		FaPai();

		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				m_pIUserItem[i].cbUserStatus = Constants.US_PLAY;
			}
		}
		m_bTableStarted = true;
		m_bGameStarted = true;

	}

	void OnEventGameEnd(int bySeatID, int cbReason) {
		m_bGameStarted = false;
		int cntUser = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				cntUser++;
			}
		}
		if (cbReason != Constants.GAME_END_DISMISS) {

			m_wJieSuanRound++;

			SUBCMD_S_JIESUAN cmd = new SUBCMD_S_JIESUAN();
			cmd.byRound = m_byRound;
			cmd.byZhuang = m_byZhuang;
			cmd.byLianZhuang = m_byLianZhuang;
			for (int i = 0; i < 4; i++) {
				cmd.winScore[i] = m_vecRoundScore[i];
				cmd.resultScore[i] = m_pIUserItem[i].lUserScore;
			}
			for (int i = 0; i < 4; i++) {

				cmd.userJieSuan[i].lRoundScore = m_vecRoundScore[i];
				cmd.userJieSuan[i].strHuType = m_vecHuType[i];

				MajSide l_MajSide = m_MajLogic.GetMajSide(i);

				Constants.memcpy(cmd.userJieSuan[i].byHandMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
				if (m_bIsHu[i] && cmd.userJieSuan[i].byHandMj[Constants.HAND_MJ_MAX - 1] == Constants.INVALID_CARD) {
					cmd.userJieSuan[i].byHandMj[Constants.HAND_MJ_MAX - 1] = m_MajLogic.GetLastOutMj();
				}
				Constants.memcpy(cmd.userJieSuan[i].hu, l_MajSide.hu);
			}
			SendData(cmd.getJsonData());
		}

		for (int i = 0; i < 4; i++) {
			m_kReport[i].lUid = m_pIUserItem[i].dwUserID;

			m_kReport[i].lResultScore = m_vecResultScore[i];
		}
		if (m_byRound <= 1 && cbReason == GAME_END_DISMISS && m_wJieSuanRound < 1) {
			SUBCMD_S_DismissRoom cmd = new SUBCMD_S_DismissRoom();
			cmd.lUid = 0L;
			cmd.cbResult = 0;
			cmd.m_wUserChairID = 0;
			cmd.m_dwTableID = m_dwTableID;

			SendData(cmd.getJsonData());
			DelayRemove();

			QpGameMgr.getInstance().OnDismissRoom(this);

		} else if (m_byRound >= m_byMaxRound || cbReason == GAME_END_DISMISS) {
			int before_cost[] = new int[5];
			int after_cost[] = new int[5];

			int cost[] = new int[5];
			for (int i = 0; i < 5; i++) {
				before_cost[i] = 0;
				cost[i] = 0;
				after_cost[i] = 0;
			}

			for (int i = 0; i < 4; i++) {
				if (m_pIUserItem[i].dwUserID > 0) {
					SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
					if (user != null) {
						before_cost[i] = user.getGem(0);
					}
				}
			}
			int minRound = 1;
			if (m_byMaxRound > 8) {
				minRound = 4;
			}
			if (m_byRound >= minRound) {
				if (m_payWay.equalsIgnoreCase("WINPAY")) {
					List<Integer> winuser = new ArrayList<Integer>();
					if (m_vecRoundScore[0] == m_vecRoundScore[1] && m_vecRoundScore[0] == m_vecRoundScore[2]
							&& m_vecRoundScore[0] == m_vecRoundScore[3]) {
						winuser.add(0);
						winuser.add(1);
						winuser.add(2);
						winuser.add(3);
					} else {
						int max = -1;
						for (int i = 0; i < 4; i++) {
							if (m_vecRoundScore[i] > max) {
								max = m_vecRoundScore[i];
							}
						}
						for (int i = 0; i < 4; i++) {
							if (m_vecRoundScore[i] == max) {
								winuser.add(i);
							}
						}
					}
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					cost_gem /= winuser.size();

					for (int i = 0; i < 5; i++) {
						if (m_pIUserItem[i].dwUserID > 0 && winuser.indexOf(i) != -1) {
							SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
							if (user != null && cost_gem < 20) {
								user.getGem(0 - cost_gem);
								cost[i] = 0 - cost_gem;
							}
						}
					}
				}
				if (m_payWay.equalsIgnoreCase("FZPAY")) {
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();

					if (m_Creator > 0) {
						SHMUser user = dthall.getInstance().getUserInfo(m_Creator);
						if (user != null && cost_gem < 100) {
							user.getGem(0 - cost_gem);
						}
					} else {
						SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[0].dwUserID);
						if (user != null && cost_gem < 100) {
							user.getGem(0 - cost_gem);
						}
						cost[0] = 0 - cost_gem;
					}
				}
				if (m_payWay.equalsIgnoreCase("AAPAY")) {
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					for (int i = 0; i < 5; i++) {
						if (m_pIUserItem[i].dwUserID > 0) {
							SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
							if (user != null && cost_gem < 20) {
								user.getGem(0 - cost_gem);
								cost[i] = 0 - cost_gem;
							}
						}
					}
				}
				if(m_payWay == "CLUBPAY"){
					float rate = m_byRound * 1.0f / m_byMaxRound;
					rate *= m_maxCostGem;
					Float frate = new Float(rate);
					int cost_gem = frate.intValue();
					DbInfoMgr.getInstance().costClubOwnerGem(this.m_clubOwnerId,cost_gem);
				}
				for (int i = 0; i < 5; i++) {
					if (m_pIUserItem[i].dwUserID > 0) {
						SHMUser user = dthall.getInstance().getUserInfo(m_pIUserItem[i].dwUserID);
						if (user != null) {
							after_cost[i] = user.getGem(0);
						}
					}
				}
			}

			SUBCMD_S_REPORT cmd = new SUBCMD_S_REPORT();
			cmd.cbReason = cbReason;
			cmd.cbType = 0;
			// Constants.memcpy(cmd.userReport, m_kReport,
			// Constants.sizeof(m_kReport));
			for (int i = 0; i < 4; i++) {
				cmd.userReport[i].lUid = m_kReport[i].lUid;
				cmd.userReport[i].cntZiMo = m_kReport[i].cntZiMo;
				cmd.userReport[i].cntHu = m_kReport[i].cntHu;
				cmd.userReport[i].cntDianPao = m_kReport[i].cntDianPao;
				cmd.userReport[i].cntGang = m_kReport[i].cntGang;
				cmd.userReport[i].cntAnGang = m_kReport[i].cntAnGang;
				cmd.userReport[i].lWinScore = m_kReport[i].lWinScore;
				cmd.userReport[i].lLoseScore = m_kReport[i].lLoseScore;
				cmd.userReport[i].lResultScore = m_kReport[i].lResultScore;
				cmd.userReport[i].dianPaoHu = m_kReport[i].cntHu - m_kReport[i].cntZiMo;
				m_vecResultScore[i] = m_kReport[i].lResultScore;
			}

			SendData(cmd.getJsonData());

			log_counter++;
			log_counter = log_counter % 100;
			Long t = System.currentTimeMillis() / 1000;
			Long battle_id = (t % 1000000) * 100 + log_counter;

			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String created = df.format(new Date());
			{

				JSONObject root = new JSONObject();

				root.put("command", "save_battle_log");
				root.put("battle_id", battle_id);

				root.put("room_type", GetType());
				root.put("hallwfdesc", m_strParam);

				root.put("room_id", m_dwTableID);
				root.put("creator", GetCreator());

				root.put("jushu", m_byMaxRound);
				root.put("limitscore", 0);

				if (m_payWay == "FZPAY") {
					root.put("payway", 0);
				} else if (m_payWay == "AAPAY") {
					root.put("payway", 1);
				} else {
					root.put("payway", 2);
				}
				root.put("created", created);
				root.put("uid0", m_pIUserItem[0].dwUserID);
				root.put("nickname0", m_pIUserItem[0].szNickName);
				root.put("score0", m_vecResultScore[0]);
				root.put("cost0", cost[0]);
				root.put("headurl0", m_TouXiang[0]);
				root.put("uid1", m_pIUserItem[1].dwUserID);
				root.put("nickname1", m_pIUserItem[1].szNickName);
				root.put("score1", m_vecResultScore[1]);
				root.put("cost1", cost[1]);
				root.put("headurl1", m_TouXiang[1]);
				root.put("uid2", m_pIUserItem[2].dwUserID);
				root.put("nickname2", m_pIUserItem[2].szNickName);
				root.put("score2", m_vecResultScore[2]);
				root.put("cost2", cost[2]);
				root.put("headurl2", m_TouXiang[2]);
				root.put("uid3", m_pIUserItem[3].dwUserID);
				root.put("nickname3", m_pIUserItem[3].szNickName);
				root.put("score3", m_vecResultScore[3]);
				root.put("cost3", cost[3]);
				root.put("headurl3", m_TouXiang[3]);
				root.put("uid4", 0);
				root.put("nickname4", "");
				root.put("score4", 0);
				root.put("cost4", 0);
				root.put("battle_video", "");
				
				if(m_clubId != 0){
					//club
					root.put("clubid", m_clubId);
					root.put("wfdesc", m_wanFaStr);
					if(m_payWay == "CLUBPAY"){
						root.put("payway", 10);
					}
					ClubRedis.getInstance().addClubBattleLog(m_clubId,root.toString());
				}

				try {
					for (int i = 0; i < 5; i++) {
						if (m_pIUserItem[i].dwUserID > 0 && cost[i] != 0) {
							JSONObject root_cost = new JSONObject();
							root_cost.put("command", "save_charge_log");
							root_cost.put("created", created);
							root_cost.put("uid", (int) m_pIUserItem[i].dwUserID);
							root_cost.put("before_cost", (int) before_cost[i]);
							root_cost.put("after_cost", (int) after_cost[i]);
							root_cost.put("cost", (int) cost[i]);
							root_cost.put("reason", " û " + m_pIUserItem[0].dwUserID + "          ˸ " + m_byMaxRound
									+ "   " + m_payWay);
							root_cost.put("room_id", m_dwTableID);
							GameDB.getInstance().push_task(null, root_cost);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				Replay.save(m_dwTableID, new org.json.JSONObject(root.toString()));
			}

			m_bTableStarted = false;
			m_startGpsCheck = false;
			for (int i = 0; i < 4; i++) {// 清除牌局数据
				m_vecResultScore[i] = 0;
			}

			DelayRemove();

			QpGameMgr.getInstance().OnDismissRoom(this);
		}
	}

	private long time(Object object) {
		return System.currentTimeMillis();
	}

	public static int GAME_END_DISMISS = Constants.GAME_END_DISMISS;

	private void SendData(String jsonData) {
		SendData(Constants.INVALID_CHAIR, jsonData);
	}

	static int log_counter = 0;

	public int m_wDealErrorDelay = 0;
	public long m_dingQueStartTime = 0;

	void OnDingQueStart() {
		m_dingQueStartTime = System.currentTimeMillis() / 1000;
		Init(Constants.INIT_NEWROUND);
		SUBCMD_S_DingQueTime cmd = new SUBCMD_S_DingQueTime();
		cmd.dingQueTime = 15;
		SendData(Constants.INVALID_CHAIR, cmd.getJsonData());
	}

	void OnDingQueFinished() {
		m_dingQueStartTime = 0;
		// 发送跑分，没有的默认跑分
		for (int i = 0; i < 4; i++) {
			MajSide l_MajSide = m_MajLogic.GetMajSide(i);
			int byTempMj[] = new int[Constants.HAND_MJ_MAX];
			Constants.memcpy(byTempMj, l_MajSide.Maj, Constants.HAND_MJ_MAX);
			//MajHelper.SortCard(byTempMj, Constants.HAND_MJ_MAX,m_vecResultDingQue[bySeatID]);
			int wanCount = 0;
			int tongCount = 0;
			int tiaoCount = 0;
			int dq = 0;
			if (m_vecResultDingQue[i] == 0) {
				for (int k = 0; k < byTempMj.length; k++) {

					if (0 < byTempMj[k] && byTempMj[k] < 10) {
						wanCount++;
					}
					if (10 < byTempMj[k] && byTempMj[k] < 20) {
						tongCount++;
					}
					if (20 < byTempMj[k] && byTempMj[k] < 30) {
						tiaoCount++;
					}
				}
				dingqueren++;
				
			}
			if (m_vecResultDingQue[i] == 0) {
			dq = wanCount <= tongCount ? wanCount : tongCount;
			dq = dq <= tiaoCount ? dq : tiaoCount;
			if (dq == wanCount) {
				m_vecResultDingQue[i] = 1;
			}
			if (dq == tongCount) {
				m_vecResultDingQue[i] = 2;
			}
			if (dq == tiaoCount) {
				m_vecResultDingQue[i] = 3;
			}
			}
		}
		SUBCMD_S_DingQue cmd = new SUBCMD_S_DingQue();
		cmd.DingQue = m_vecResultDingQue;
		SendData(cmd.getJsonData());

	}

	void OnDealAI(float dt) {
		m_DealTime = (int) (System.currentTimeMillis() / 1000);

		if (m_wChuPaiDelay > 0) {
			m_wChuPaiDelay--;
			return;
		}
		int cntRobot = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 1) {
				cntRobot++;
			}
		}

		int cntActionRight = 0;
		for (int i = 0; i < 4; i++) {
			if (GetActionRight(i) > 0) {
				if (m_pIUserItem[i].isAndroidUser == 1) {
					CleanTempRight(i);
				} else {
					cntActionRight++;
				}
			}
		}

		int cntMoPaiUser = 0;
		for (int j = 0; j < 4; j++) {
			if (m_MajLogic.GetMajSide(j).GetHandMjCount() % 3 == 2) {
				cntMoPaiUser++;
			}
		}
		if (cntMoPaiUser == 0) {
			m_wDealErrorDelay++;
		}
		if (cntActionRight == 0) {

			if (cntMoPaiUser == 0 && m_MajLogic.GetCurrentUser() < 4) {

				if (m_wDealErrorDelay > 1) {
					int byLastUser = m_MajLogic.GetLastUser();
					int byNextUser = Constants.INVALID_CHAIR;
					if (byLastUser == m_MajLogic.GetCurrentUser()) {
						byNextUser = MajHelper.GetNextUser(byLastUser);
					} else {
						byNextUser = m_MajLogic.GetCurrentUser();
					}

					if (m_MajLogic.m_byOutMjCount == 0) {
						byNextUser = m_byZhuang;
					}
					MajSide l_NextMajSide = m_MajLogic.GetMajSide(byNextUser);
					int byHandMjCount = l_NextMajSide.GetHandMjCount();
					if (byHandMjCount % 3 == 1) {
						m_isBusy = true;
						OnUserTouchMj(byNextUser, 0);
						m_isBusy = false;
						m_wChuPaiDelay = 1;
						for (int i = 0; i < 4; i++) {
							m_wRobotSeconds[i] = 0;
						}
					} else if (byHandMjCount % 3 == 0) {
						for (int i = Constants.HAND_MJ_MAX - 1; i >= 0; i--) {
							if (l_NextMajSide.Maj[i] != INVALID_CARD) {
								l_NextMajSide.Maj[i] = INVALID_CARD;
								break;
							}
						}
					}
				}
			} else {
				int byCurrentUser = m_MajLogic.GetCurrentUser();
				if (byCurrentUser == 0 || GetActionRight(0) > 0) {
					return;
				}
				m_wRobotSeconds[byCurrentUser]++;
				if (m_pIUserItem[byCurrentUser].isAndroidUser == 1
						&& (m_MajLogic.GetMajSide(byCurrentUser).GetMoPai() != INVALID_CARD)) {
					m_isBusy = true;
					OnUserOutMj(byCurrentUser, m_MajLogic.GetMajSide(byCurrentUser).GetMoPai());
					m_isBusy = false;
					for (int i = 0; i < 4; i++) {
						m_wRobotSeconds[i] = 0;
					}
				} else {
					if (m_wRobotSeconds[byCurrentUser] >= 15 && cntRobot != 0) {
						/*
						 * if (m_MajLogic.GetMajSide(byCurrentUser).GetMoPai()
						 * != INVALID_CARD ||
						 * m_MajLogic.GetMajSide(byCurrentUser).GetHandMjCount()
						 * % 3 == 2) {
						 * if(m_MajLogic.GetMajSide(byCurrentUser).GetMoPai() !=
						 * INVALID_CARD) { OnUserOutMj(byCurrentUser,
						 * m_MajLogic.GetMajSide(byCurrentUser).GetMoPai());
						 * }else{ OnUserOutMj(byCurrentUser,
						 * m_MajLogic.GetMajSide(byCurrentUser).GetMoPai()); }
						 * 
						 * for (int i = 0; i < 4; i++) { m_wRobotSeconds[i] = 0;
						 * } }
						 */
					}
				}
			}
		} else {
			if (cntRobot > 1) {
				if (m_wDealErrorDelay > 1) {
					for (int i = 0; i < 4; i++) {
						MajSide l_MajSide = m_MajLogic.GetMajSide(i);
						int byHandMjCount = l_MajSide.GetHandMjCount();
						if (byHandMjCount % 3 == 0) {
							for (int j = Constants.HAND_MJ_MAX - 1; j >= 0; j--) {
								if (l_MajSide.Maj[j] != INVALID_CARD) {
									l_MajSide.Maj[j] = INVALID_CARD;
									break;
								}
							}
						}
					}
				}
				for (int i = 0; i < 4; i++) {
					m_wRobotSeconds[i]++;
					if (m_wRobotSeconds[i] > 600 && GetActionRight(i) > 0
							&& m_MajLogic.GetMajSide(i).GetMoPai() == INVALID_CARD
							&& m_MajLogic.GetMajSide(i).GetHandMjCount() % 3 != 2) {
						SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
						m_isBusy = true;
						OnUserGiveUp(i, guo);
						m_isBusy = false;
						CleanTempRight(i);
						m_wRobotSeconds[i] = 0L;
					}
				}
			}
		}
	}

	int INVALID_CARD = Constants.INVALID_CARD;
	int INIT_TOTAL = Constants.INIT_TOTAL;

	public void OnDeal(int dt) {
		if (m_isBusy) {
			return;
		}
		if (m_bGameStarted == true) {
			if (GetRobotCount() == GetPlayerCount()) {
				Init(INIT_TOTAL);
			} else {
				OnDealAI(dt);
			}
		}
		if (m_dingQueStartTime != 0) {
			long currTime = System.currentTimeMillis() / 1000;
			if (currTime - m_dingQueStartTime >= 15) {
				OnDingQueFinished();
			}
		}
		if (m_bGameStarted == false) {
		}
	}

	static int randRobotIndex = 999;

	int AddRobot() {

		randRobotIndex++;
		int robot_uid = randRobotIndex % 9999 + 200000;

		ArrayList<Integer> vecEmpty = new ArrayList<>();
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID == 0) {
				vecEmpty.add(i);
			}
		}
		if (vecEmpty.size() > 0) {
			int rand = Constants.rand();
			int wChairID = vecEmpty.get(rand % vecEmpty.size());

			int vecMaleFace[] = { 1, 3, 5, 7, 9 };
			int vecFemaleFace[] = { 2, 4, 6, 8, 10 };
			m_pIUserItem[wChairID].dwUserID = robot_uid;
			m_pIUserItem[wChairID].lUserScore = 0;
			m_pIUserItem[wChairID].wChairID = wChairID;
			m_pIUserItem[wChairID].cbGender = (rand % 2);
			if (m_pIUserItem[wChairID].cbGender == 1) {
				m_pIUserItem[wChairID].dwFaceID = vecMaleFace[rand % 5];
			} else {
				m_pIUserItem[wChairID].dwFaceID = vecFemaleFace[rand % 5];
			}
			m_pIUserItem[wChairID].cbUserStatus = US_NULL;
			m_pIUserItem[wChairID].isAndroidUser = 1;

			m_pIUserItem[wChairID].szNickName = "USER[" + wChairID + "]";

			{
				SUBCMD_S_Sit cmd = new SUBCMD_S_Sit();
				// memset(&cmd, 0, sizeof(cmd));

				cmd.m_lUid = robot_uid;
				cmd.m_wUserChairID = m_pIUserItem[wChairID].wChairID;
				cmd.m_lUserScore = m_pIUserItem[wChairID].lUserScore;
				cmd.m_iAvatar = m_pIUserItem[wChairID].dwFaceID;
				cmd.szNickName = m_pIUserItem[wChairID].szNickName;
				cmd.szIP = m_pIUserItem[wChairID].szIP;

				SendData(cmd.getJsonData());
			}
			{
				m_pIUserItem[wChairID].cbUserStatus = Constants.US_READY;

				SUBCMD_S_Ready cmd = new SUBCMD_S_Ready();
				// memset(&cmd, 0, sizeof(cmd));

				cmd.m_lUid = robot_uid;
				cmd.m_wUserChairID = m_pIUserItem[wChairID].wChairID;

				SendData(cmd.getJsonData());
			}
			m_wRobotSeconds[wChairID] = (long) 0;
			return m_pIUserItem[wChairID].wChairID;
		}
		return 0;
	}

	int US_NULL = Constants.US_NULL;

	void Handle_onJoin(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 5) {
			m_pIUserItem[bySeatID].cbOnline = US_NULL;
		}

		SUBCMD_S_Join cmd = new SUBCMD_S_Join();
		// memset(&cmd, 0, sizeof(cmd));

		SendData(_Uid, cmd.getJsonData());
	}

	void Handle_onReady(int _Uid, String[] vecArg) {
		if (m_bGameStarted == true) {
			return;
		}
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 4) {
			m_pIUserItem[bySeatID].cbUserStatus = Constants.US_READY;
		}
		int cntReady = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].cbUserStatus == Constants.US_READY || m_pIUserItem[i].isAndroidUser == 1) {
				cntReady++;
			}
		}
		SUBCMD_S_Ready cmd = new SUBCMD_S_Ready();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = bySeatID;
		cmd.m_dwTableID = m_dwTableID;
		SendData(cmd.getJsonData());
		if (cntReady == 4) {
			SUBCMD_S_cuntReady cmdReady = new SUBCMD_S_cuntReady();
			cmdReady.cntReady = 4;
			SendData(cmdReady.getJsonData());
			OnEventGameStart();
		} else {

		}
	}

	void Handle_onRobot(int _Uid, String[] vecArg) {
		String s = vecArg[1];
		System.out.println(s);
		if (m_bGameStarted == true) {
			return;
		}
		int bySeatID = FindSeat(_Uid);
		if (bySeatID < 4) {
			m_pIUserItem[bySeatID].cbUserStatus = Constants.US_READY;
		}
		int cntPlayer = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0) {
				cntPlayer++;
			}
		}
		if (cntPlayer < 4) {
			for (int i = 0; i < 4 - cntPlayer; i++) {
				AddRobot();
			}
		}
	}

	// 摸牌: mopai|bySeatID|byMj|bChi,bPeng,bGang,bTing,bHu
	void Handle_onTryMoPai(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		m_isBusy = true;
		// OnUserTouchMj(bySeatID,0);
		m_isBusy = false;
	}

	// 摸牌: mopai|bySeatID|byMj|bChi,bPeng,bGang,bTing,bHu
	void Handle_onMoPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID != m_MajLogic.GetCurrentUser()) {
			return;
		}
		m_isBusy = true;
		OnUserTouchMj(bySeatID, 0);
		m_isBusy = false;
	}

	// 出牌: chupai|bySeatID|byOutMj|byActionTingPai
	// 出牌:
	// chupai|bySeatID|byMj|bAllowChi,bAllowPeng,bAllowGang,bAllowHu|byTing|byKeHuPai
	void Handle_onChuPai(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);

		if (bySeatID < 4) {
			MajSide l_MajSide = m_MajLogic.GetMajSide(bySeatID);
			int byHandMjCount = l_MajSide.GetHandMjCount();
			if (byHandMjCount % 3 == 0) {
				for (int j = Constants.HAND_MJ_MAX - 1; j >= 0; j--) {
					if (l_MajSide.Maj[j] != INVALID_CARD) {
						l_MajSide.Maj[j] = INVALID_CARD;
						break;
					}
				}
			}
			byHandMjCount = l_MajSide.GetHandMjCount();
			if (byHandMjCount % 3 == 2) {
				m_MajLogic.SetCurrentUser(bySeatID);
				int byOutMj = atoi(vecArg[2]);
				int byActionTingPai = atoi(vecArg[3]);

				m_isBusy = true;
				OnUserOutMj(bySeatID, byOutMj);
				m_isBusy = false;
			}
		}
	}

	void Handle_onBaoZiPai(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		OnUserBaoZi(bySeatID);
	}

	void Handle_InBack(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {
			return;
		}

		SUBCMD_S_InBack cmd = new SUBCMD_S_InBack();
		cmd.byActionUser = wChairID;
		SendData(cmd.getJsonData());
	}

	// 定缺
	void Handle_onDingQue(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {
			return;
		}
		int selectMJ = Integer.parseInt(vecArg[1]);
		m_dingQuemj = selectMJ;
		SUBCMD_S_DingQue cmd = new SUBCMD_S_DingQue();
		cmd.byActionUser = wChairID;
		cmd.dingQueMJ = selectMJ;

		m_vecResultDingQue[wChairID] = Integer.parseInt(vecArg[1]);
		for (int i = 0; i < 4; i++) {
			cmd.DingQue[i] = m_vecResultDingQue[i];
		}

		SendData(cmd.getJsonData());
		dingqueren++;
	}

	void Handle_InFore(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {
			return;
		}

		SUBCMD_S_InFore cmd = new SUBCMD_S_InFore();		
		cmd.byActionUser = wChairID;
		SendData(cmd.getJsonData());
	}

	void Handle_ClientIp(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		// m_pIUserItem[bySeatID].szIP = vecArg[1];
	}

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	/**
	 * 通过经纬度获取距离(单位：米)
	 * 
	 * @param lat1
	 * @param lng1
	 * @param lat2
	 * @param lng2
	 * @return
	 */
	private static double EARTH_RADIUS = 6378.137;

	public static double getDistance(double lat1, double lng1, double lat2, double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(
				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = Math.round(s * 10000d) / 10000d;
		s = s * 1000;
		return s;
	}

	void Handle_ClientGps(int _Uid, String[] vecArg) {
		try {
			// 游戏开始10s后才开始提示

			int bySeatID = FindSeat(_Uid);
			if (bySeatID == Constants.INVALID_CHAIR) {
				return;
			}
			double lat = Double.parseDouble(vecArg[1]);
			double lon = Double.parseDouble(vecArg[2]);

			// 检测玩家的距离是否分开

			m_gpsData[bySeatID].lat = lat;
			m_gpsData[bySeatID].lon = lon;

		} catch (Exception e) {

		}
	}

	void checkNullGps() {
		// 处理读取不到gps信息的
		SUBCMD_S_GpsNull nullcmd = new SUBCMD_S_GpsNull();
		boolean needSend = false;
		for (int i = 0; i < 4; i++) {
			if (m_gpsData[i].lat == 0.0 && m_gpsData[i].lon == 0.0) {
				needSend = true;
				nullcmd.addNullGps(i);
			}
		}
		if (needSend)
			SendData(nullcmd.getJsonData());
	}

	boolean OnUserBaoZi(int bySeatID) {
		if (bySeatID >= 4) {
			return false;
		}
		if (m_bGameStarted == false) {
			return false;
		}
		if (m_byChuPaiCount[bySeatID] == 0) {
			m_baoZiTing[bySeatID] = true;
		}

		m_MajLogic.SetCurrentAction(Constants.ACTION_TING);
		SUBCMD_S_BaoZi cmd = new SUBCMD_S_BaoZi();
		cmd.byActionUser = bySeatID;

		m_MajLogic.GetMajSide(bySeatID).byBaoZi = 1;

		String sData = cmd.getJsonData();
		SendData(Constants.INVALID_CHAIR, sData);
		m_wDealErrorDelay = 0;
		return false;
	}

	// 吃牌: chipai|bySeatID|byChiMj|byChiMode|byOutMj
	void Handle_onChiPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}
		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			clearUserHuRound(bySeatID);
			CleanTempRight(bySeatID);
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}

		int byChiMode = atoi(vecArg[2]);
		SUBCMD_C_Chi chi = new SUBCMD_C_Chi();
		chi.nRight = 0;
		chi.nChiType = byChiMode;
		m_isBusy = true;
		OnUserChi(bySeatID, chi);
		m_isBusy = false;
		return;
	}

	// 碰牌: pengpai|bySeatID|byPengMj|byOutMj
	void Handle_onPengPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}

		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			clearUserHuRound(bySeatID);
			CleanTempRight(bySeatID);
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}
		SUBCMD_C_Operation peng = new SUBCMD_C_Operation();
		m_isBusy = true;
		OnUserPeng(bySeatID, peng);
		m_isBusy = false;

		return;

	}

	// 杠牌: gangpai|bySeatID|byGangMj|byGangMode|byBuMj|byAddBaoPai
	void Handle_onGangPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}
		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			CleanTempRight(bySeatID);
			clearUserHuRound(bySeatID);
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}
		int byGangMj = atoi(vecArg[1]);
		int byGangMode = atoi(vecArg[2]);

		SUBCMD_C_Gang gang = new SUBCMD_C_Gang();
		gang.nRight = 0;
		gang.nGangMode = byGangMode;
		gang.byGangMj = byGangMj;

		m_isBusy = true;
		OnUserGang(bySeatID, gang);
		m_isBusy = false;

		return;

	}

	// 胡牌: hupai|bySeatID|hu_mode
	void Handle_onHuPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		renew_kehupai(bySeatID);
		if (this.m_roundHuCount != 0) {
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount)
				this.Handle_onYiPaoSanXiangHu(bySeatID);
		} else {
			SUBCMD_C_Hu hu = new SUBCMD_C_Hu();
			OnUserHu(bySeatID, hu, 1);
		}
		return;
	}

	// 胡牌: hupai|bySeatID|hu_mode
	void Handle_onGuoPai(int _Uid, String[] vecArg) {

		int bySeatID = FindSeat(_Uid);
		if (bySeatID == INVALID_CHAIR) {
			return;
		}

		if (this.m_roundHuCount != 0 && this.IsInRoundHu(bySeatID)) {
			CleanTempRight(bySeatID);
			clearUserHuRound(bySeatID);
			this.m_roundHuGetCount++;
			if (this.m_roundHuCount == this.m_roundHuGetCount) {
				this.Handle_onYiPaoSanXiangHu(bySeatID);
				return;
			}
		}

		SUBCMD_C_Operation guo = new SUBCMD_C_Operation();
		m_isBusy = true;
		OnUserGiveUp(bySeatID, guo);
		m_isBusy = false;
		return;
	}

	int INVALID_CHAIR = Constants.INVALID_CHAIR;

	// 表情
	void Handle_onBiaoQing(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}

		int index = atoi(vecArg[1]);

		SUBCMD_S_BiaoQing cmd = new SUBCMD_S_BiaoQing();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.m_iBiaoQingIndex = index;

		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onYuYin(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == INVALID_CHAIR) {

			return;
		}

		int index = atoi(vecArg[1]);

		SUBCMD_S_YuYin cmd = new SUBCMD_S_YuYin();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.m_iYuYinIndex = index;

		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onText(int _Uid, String[] vecArg) {

		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		String strContent = vecArg[1];	
		String iter = dthall.getInstance().m_mapAvatar.get(_Uid);				
		
			String szAvatarURL = "http://lamj.qilehuyu.cn/liuan-80.png";
	
		if(!StringUtils.isEmpty(iter)){
			m_vecInputWenZi+=iter+";"+_Uid+";"+strContent+",";
		}
		else{
			m_vecInputWenZi+=szAvatarURL+";"+_Uid+";"+strContent+",";
		}
							
		strContent = string_replace(strContent, "|", ".");
		strContent = string_replace(strContent, "#", ".");
		strContent = string_replace(strContent, ",", ".");
		strContent = string_replace(strContent, "\\", ".");
		strContent = string_replace(strContent, "'", ".");
		strContent = string_replace(strContent, "\"", ".");

		SUBCMD_S_Text cmd = new SUBCMD_S_Text();
	
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.szContent = strContent;
		cmd.InputWenZi=m_vecInputWenZi;
		SendData(cmd.getJsonData());
	}

	private String string_replace(String strContent, String string, String string2) {
		return strContent.replace(string, string2);
	}

	// 送礼
	void Handle_onSongLi(int _Uid, String[] vecArg) {
	}

	// 聊天
	void Handle_onChat(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {

			return;
		}
		String strContent = vecArg[1];

		SUBCMD_S_Chat cmd = new SUBCMD_S_Chat();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.szContent = strContent;
		SendData(cmd.getJsonData());
	}

	// 语音
	void Handle_onVoice(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		int seconds = atoi(vecArg[1]);
		String strVoiceURL = vecArg[2];

		System.out.println(strVoiceURL);
		SUBCMD_S_Voice cmd = new SUBCMD_S_Voice();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.seconds = seconds;
		cmd.szVoiceURL = strVoiceURL;

		SendData(cmd.getJsonData());
	}

	void Handle_onVoiceMsg(int _Uid, String[] vecArg) {
		int wChairID = FindSeat(_Uid);
		if (wChairID == Constants.INVALID_CHAIR) {
			return;
		}
		float seconds = Float.parseFloat(vecArg[1]);

		SUBCMD_S_VoiceMsg cmd = new SUBCMD_S_VoiceMsg();
		cmd.m_lUid = _Uid;
		cmd.m_wUserChairID = wChairID;
		cmd.seconds = seconds;

		cmd.data = vecArg[2];
		cmd.m_maxClip = Integer.parseInt(vecArg[3]);
		cmd.m_currClip = Integer.parseInt(vecArg[4]);
		SendData(cmd.getJsonData());
	}

	private int atoi(String string) {
		try {
			return Integer.parseInt(string);
		} catch (Exception e) {
		}
		return 0;
	}

	// 语音
	void Handle_onTryDismissRoom(int _Uid, String vecArg[]) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		if (vecArg.length < 2)
			return;
		String attachInfo = vecArg[1];
		if (attachInfo.equals("fzquit")) {
			// 房主请求直接退出
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
			return;
		}
		int cntUser = 0;
		int cntOnline = 0;
		int cntOffline = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				cntUser++;
			}
		}
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				if (m_pIUserItem[i].cbOnline == Constants.US_OFFLINE) {
					cntOffline++;
				} else {
					cntOnline++;
				}
			}
		}
		if (cntUser > 1) {
			if (m_dismissTimer == 0) {
				m_dismissTimer = System.currentTimeMillis() / 1000;
			}
			m_byAgreeDismiss[bySeatID] = 1;

			SUBCMD_S_TryDismissRoom cmd = new SUBCMD_S_TryDismissRoom();
			cmd.lUid = _Uid;
			cmd.dwTableID = m_dwTableID;
			cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

			SendData(Constants.INVALID_CHAIR, cmd.getJsonData());

			if (cntOnline == 1) {
				OnEventGameEnd(0, Constants.GAME_END_DISMISS);
				DelayRemove();
				QpGameMgr.getInstance().OnDismissRoom(this);

				m_dismissTimer = 0;
			}
		} else {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
		}

	}

	// 语音
	void Handle_onAgreeDismissRoom(int _Uid, String vecArg[]) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {
			return;
		}
		if (vecArg.length < 2)
			return;
		m_byAgreeDismiss[bySeatID] = 1;

		SUBCMD_S_AgreeDismissRoom cmd = new SUBCMD_S_AgreeDismissRoom();
		cmd.lUid = _Uid;
		cmd.dwTableID = m_dwTableID;
		cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

		SendData(Constants.INVALID_CHAIR, cmd.getJsonData());

		if (bySeatID == 0 && m_bTableStarted == false) {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);
			return;
		}
		int cntAgree = 0;
		for (int i = 0; i < 4; i++) {
			if (m_byAgreeDismiss[i] > 0) {
				cntAgree++;
			}
		}
		int cntUser = 0;
		for (int i = 0; i < 4; i++) {
			if (m_pIUserItem[i].dwUserID > 0 && m_pIUserItem[i].isAndroidUser == 0) {
				cntUser++;
			}
		}
		if (cntAgree >= 2 && cntAgree >= cntUser - 1) {
			OnEventGameEnd(0, Constants.GAME_END_DISMISS);
			DelayRemove();
			QpGameMgr.getInstance().OnDismissRoom(this);

			if (ShouldBeRemoved()) {
				// niuniuTableMgr::instance().DismissTable(this);
			}
		}
	}

	// 语音
	void Handle_onRefuseDismissRoom(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {

			return;
		}

		m_dismissTimer = 0L;
		m_byAgreeDismiss[0] = 0;
		m_byAgreeDismiss[1] = 0;
		m_byAgreeDismiss[2] = 0;
		m_byAgreeDismiss[3] = 0;

		SUBCMD_S_RefuseDismissRoom cmd = new SUBCMD_S_RefuseDismissRoom();
		cmd.lUid = (long) _Uid;
		cmd.dwTableID = m_dwTableID;
		cmd.szNickName = m_pIUserItem[bySeatID].szNickName;

		SendData(cmd.getJsonData());
	}

	//
	void Handle_onReload(int _Uid, String[] vecArg) {
		int bySeatID = FindSeat(_Uid);
		if (bySeatID == Constants.INVALID_CHAIR) {

			return;
		}

		OnUserSit(_Uid);
	}

	public int m_DealTime = 0;

	@Override
	public int getDealTime() {
		return m_DealTime;
	}

	public boolean m_bRemove = false;

	public void DelayRemove() {
		m_bRemove = true;
	}

	public void ResetKillFlag() {
		m_bRemove = false;
	}

	public boolean ShouldBeRemoved() {
		return m_bRemove;
	}

	@Override
	public String getRoomInfo() {
		// TODO 自动生成的方法存根
		// m_lStartTime
		// m_pIUserItem
		// m_bTableStarted;
		// m_byRound;
		// m_byMaxRound;
		// m_dwTableID
		String roomInfo = String.format("%s|%s|%s|%s|%s", m_pIUserItem[0].GetUserInfo(), // #
				m_pIUserItem[1].GetUserInfo(), m_pIUserItem[2].GetUserInfo(), m_pIUserItem[3].GetUserInfo(),
				m_pIUserItem[4].GetUserInfo());
		String descInfo = String.format("房间类型：马店麻将   %d/%d局", m_byRound, m_byMaxRound);
		roomInfo = String.format("%s|%d|%d|%s", roomInfo, m_dwTableID, m_lStartTime, descInfo);

		return roomInfo;
	}

	@Override
	public int getPlayerCount() {
		// TODO Auto-generated method stub
		return GetPlayerCount();
	}

	@Override
	public int getCostGem() {
		// TODO Auto-generated method stub
		return m_byCostGem;
	}

	@Override
	public int getStatus() {
		// TODO Auto-generated method stub
		if (m_bTableStarted == false) {
			return 0;
		}
		return 1;
	}

	@Override
	public String getRoomDesc() {
		String desc = "霍邱麻将,";
		if (this.m_payWay == "WINPAY")
			desc += "赢家支付";
		else if (this.m_payWay == "FZPAY")
			desc += "房主支付";
		else
			desc += "AA制";
		desc += ",";
		desc += m_byMaxRound;
		desc += "局";
		desc += ",";
		if (this.m_hqDaiDaPai) {
			desc += "带大牌";
		} else {
			desc += "不带大牌";
		}
		desc += ",";
		if (this.m_hqShuiDaShuiBao) {
			desc += "谁打谁出分";
		} else {
			desc += "赢倒三家有";
		}
		return desc;
	}

	@Override
	public int getCellScore() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getMinScore() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getPayway() {
		return m_payWay;
	}

	@Override
	public String GetRoundInfo() {
		return "" + m_byRound + "/" +  m_byMaxRound;
	}
}

class SUBCMD_C_Operation {
	int byCurrentUser; // 当前用户
	int byLastUser; // 上次出牌用户
	int nRight; // 操作,6-胡,4-杠,3-碰,2-吃, 0-放弃
};

// 用户出牌
class SUBCMD_C_OutMj {
	int byOutMj; // 打出的牌
};

// 吃操作
class SUBCMD_C_Chi {
	int nRight; // 权限
	int nChiType; // 吃牌类型,0-无,1-@@*, 2-@*@, 3-*@@
};

// 碰操作无需参数，所以不单独列

// 杠操作
class SUBCMD_C_Gang {
	int nRight; // 权限
	int nGangMode; // 杠牌类型,0-无, 1-明杠,2-补杠, 4-暗杠
	int byGangMj; // 所杠的牌，自摸可以有多种杠牌的可能
};

// 杠牌选择
class SUBCMD_C_SelectGang {
	int nGangType; // 杠牌类型
	int byGangMj; // 所杠的牌
};

// 胡操作
class SUBCMD_C_Hu {
	int nRight; // 胡牌权限
};

// 明牌操作操作
class SUBCMD_C_MingPai {
	int byUser; // 明牌人
	int[] buliangMj = new int[4];
};

class M_tempAction {
	int m_ActionRight;
	// 用户操作
	SUBCMD_C_Operation m_cOperation = new SUBCMD_C_Operation();
	SUBCMD_C_OutMj m_cChuPai = new SUBCMD_C_OutMj();
	// 吃操作
	SUBCMD_C_Chi m_cChi = new SUBCMD_C_Chi();
	// 碰操作无需参数，所以不单独列
	SUBCMD_C_Operation m_cPeng = new SUBCMD_C_Operation();
	// 杠操作
	SUBCMD_C_Gang m_cGang = new SUBCMD_C_Gang();
	SUBCMD_C_SelectGang m_cSelectGang = new SUBCMD_C_SelectGang();
	// 胡操作
	SUBCMD_C_Hu m_cHu = new SUBCMD_C_Hu();
	// 杠操作
	SUBCMD_C_Operation m_cGuo = new SUBCMD_C_Operation();
	int m_kBuffer[] = new int[100];

	void Clean() {
		Constants.memset(m_kBuffer, 0, 100);
		m_ActionRight = 0;
	}
};